From 046dc269158ae8e22c9dbeb7828b0a5f6a83661f Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Fri, 8 Nov 2024 22:19:34 +0100 Subject: [PATCH 1/2] database changes --- .../WatchIt.Common.Model/Genres/Genre.cs | 3 - .../Genres/GenreQueryParameters.cs | 5 - .../Genres/GenreRequest.cs | 2 - .../Genres/GenreResponse.cs | 4 +- .../Account/AccountFollowConfiguration.cs | 31 + .../Common/GenreConfiguration.cs | 3 - .../WatchIt.Database.Model/Account/Account.cs | 3 + .../Account/AccountFollow.cs | 21 + .../WatchIt.Database.Model/Common/Genre.cs | 1 - ...200642_GenreDescriptionRemoved.Designer.cs | 1412 ++++++++++++++++ .../20241108200642_GenreDescriptionRemoved.cs | 78 + ...41108211519_AccountFollowAdded.Designer.cs | 1459 +++++++++++++++++ .../20241108211519_AccountFollowAdded.cs | 77 + .../DatabaseContextModelSnapshot.cs | 57 +- .../GenresController.cs | 8 - .../GenresControllerService.cs | 27 +- .../IGenresControllerService.cs | 1 - .../Genres/GenreRequestValidator.cs | 1 - .../Model/Genres.cs | 1 - .../WatchIt.Website/appsettings.json | 1 - 20 files changed, 3135 insertions(+), 60 deletions(-) create mode 100644 WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountFollowConfiguration.cs create mode 100644 WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/AccountFollow.cs create mode 100644 WatchIt.Database/WatchIt.Database/Migrations/20241108200642_GenreDescriptionRemoved.Designer.cs create mode 100644 WatchIt.Database/WatchIt.Database/Migrations/20241108200642_GenreDescriptionRemoved.cs create mode 100644 WatchIt.Database/WatchIt.Database/Migrations/20241108211519_AccountFollowAdded.Designer.cs create mode 100644 WatchIt.Database/WatchIt.Database/Migrations/20241108211519_AccountFollowAdded.cs diff --git a/WatchIt.Common/WatchIt.Common.Model/Genres/Genre.cs b/WatchIt.Common/WatchIt.Common.Model/Genres/Genre.cs index 2a6a26f..3a2a9af 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Genres/Genre.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Genres/Genre.cs @@ -6,7 +6,4 @@ public class Genre { [JsonPropertyName("name")] public required string Name { get; set; } - - [JsonPropertyName("description")] - public string? Description { get; set; } } \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs index 220b5e4..8c9ba18 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs @@ -10,9 +10,6 @@ public class GenreQueryParameters : QueryParameters [FromQuery(Name = "name")] public string? Name { get; set; } - [FromQuery(Name = "description")] - public string? Description { get; set; } - #endregion @@ -22,8 +19,6 @@ public class GenreQueryParameters : QueryParameters protected override bool IsMeetingConditions(GenreResponse item) => ( TestStringWithRegex(item.Name, Name) - && - TestStringWithRegex(item.Description, Description) ); #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreRequest.cs b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreRequest.cs index 27e771c..a77e95e 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreRequest.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreRequest.cs @@ -7,13 +7,11 @@ public class GenreRequest : Genre public Database.Model.Common.Genre CreateGenre() => new Database.Model.Common.Genre { Name = Name, - Description = Description, }; public void UpdateGenre(Database.Model.Common.Genre genre) { genre.Name = Name; - genre.Description = Description; } #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs index 9bb7cba..e058e98 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs @@ -12,8 +12,7 @@ public class GenreResponse : Genre, IQueryOrderable public static IDictionary> OrderableProperties { get; } = new Dictionary> { { "id", x => x.Id }, - { "name", x => x.Name }, - { "description", x => x.Description } + { "name", x => x.Name } }; @@ -34,7 +33,6 @@ public class GenreResponse : Genre, IQueryOrderable { Id = genre.Id; Name = genre.Name; - Description = genre.Description; } #endregion diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountFollowConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountFollowConfiguration.cs new file mode 100644 index 0000000..18f237e --- /dev/null +++ b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountFollowConfiguration.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using WatchIt.Database.Model.Account; + +namespace WatchIt.Database.Model.Configuration.Account; + +public class AccountFollowConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(x => x.Id); + builder.HasIndex(x => x.Id) + .IsUnique(); + builder.Property(x => x.Id) + .IsRequired(); + + builder.HasOne(x => x.AccountFollower) + .WithMany(x => x.AccountFollows) + .HasForeignKey(x => x.AccountFollowerId) + .IsRequired(); + builder.Property(x => x.AccountFollowerId) + .IsRequired(); + + builder.HasOne(x => x.AccountFollowed) + .WithMany(x => x.AccountFollowedBy) + .HasForeignKey(x => x.AccountFollowedId) + .IsRequired(); + builder.Property(x => x.AccountFollowedId) + .IsRequired(); + } +} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/GenreConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/GenreConfiguration.cs index 4b4b665..5715f7f 100644 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/GenreConfiguration.cs +++ b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Common/GenreConfiguration.cs @@ -20,9 +20,6 @@ public class GenreConfiguration : IEntityTypeConfiguration .HasMaxLength(100) .IsRequired(); - builder.Property(x => x.Description) - .HasMaxLength(1000); - // Navigation builder.HasMany(x => x.Media) .WithMany(x => x.Genres) diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs index f7f5db4..181dd59 100644 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs +++ b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs @@ -39,6 +39,9 @@ public class Account public virtual IEnumerable RatingMediaSeriesEpisode { get; set; } = new List(); public virtual IEnumerable AccountRefreshTokens { get; set; } = new List(); + + public virtual IEnumerable AccountFollows { get; set; } = new List(); + public virtual IEnumerable AccountFollowedBy { get; set; } = new List(); #endregion } \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/AccountFollow.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/AccountFollow.cs new file mode 100644 index 0000000..1783999 --- /dev/null +++ b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/AccountFollow.cs @@ -0,0 +1,21 @@ +namespace WatchIt.Database.Model.Account; + +public class AccountFollow +{ + #region PROPERTIES + + public Guid Id { get; set; } + public long AccountFollowerId { get; set; } + public long AccountFollowedId { get; set; } + + #endregion + + + + #region NAVIGATION + + public virtual Account AccountFollower { get; set; } = null!; + public virtual Account AccountFollowed { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Genre.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Genre.cs index 5d3c63b..b27e8ac 100644 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Genre.cs +++ b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Common/Genre.cs @@ -8,7 +8,6 @@ public class Genre public short Id { get; set; } public required string Name { get; set; } - public string? Description { get; set; } #endregion diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20241108200642_GenreDescriptionRemoved.Designer.cs b/WatchIt.Database/WatchIt.Database/Migrations/20241108200642_GenreDescriptionRemoved.Designer.cs new file mode 100644 index 0000000..37cd735 --- /dev/null +++ b/WatchIt.Database/WatchIt.Database/Migrations/20241108200642_GenreDescriptionRemoved.Designer.cs @@ -0,0 +1,1412 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using WatchIt.Database; + +#nullable disable + +namespace WatchIt.Database.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20241108200642_GenreDescriptionRemoved")] + partial class GenreDescriptionRemoved + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.5") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true) + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BackgroundPictureId") + .HasColumnType("uuid"); + + b.Property("CreationDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(320) + .HasColumnType("character varying(320)"); + + b.Property("GenderId") + .HasColumnType("smallint"); + + b.Property("IsAdmin") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("LastActive") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("LeftSalt") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("bytea"); + + b.Property("ProfilePictureId") + .HasColumnType("uuid"); + + b.Property("RightSalt") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("BackgroundPictureId"); + + b.HasIndex("GenderId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("ProfilePictureId") + .IsUnique(); + + b.ToTable("Accounts"); + + b.HasData( + new + { + Id = 1L, + CreationDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + Email = "root@watch.it", + IsAdmin = true, + LastActive = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + LeftSalt = "HIZYSU/94oe$[jAy\\{7V", + Password = new byte[] { 118, 180, 133, 0, 25, 6, 65, 230, 20, 221, 180, 8, 111, 189, 191, 158, 98, 160, 80, 196, 146, 99, 90, 55, 196, 219, 245, 244, 167, 89, 123, 74, 37, 92, 234, 81, 74, 199, 149, 128, 7, 213, 202, 191, 162, 62, 19, 144, 206, 83, 80, 237, 37, 179, 12, 215, 61, 179, 94, 189, 30, 98, 100, 164 }, + RightSalt = "#(^8YBkY; + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("AccountProfilePictures"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("IsExtendable") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("AccountRefreshTokens"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsHistorical") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Countries"); + + b.HasData( + new + { + Id = (short)1, + IsHistorical = false, + Name = "Afghanistan" + }, + new + { + Id = (short)2, + IsHistorical = false, + Name = "Albania" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Gender", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Genders"); + + b.HasData( + new + { + Id = (short)1, + Name = "Male" + }, + new + { + Id = (short)2, + Name = "Female" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Genres"); + + b.HasData( + new + { + Id = (short)1, + Name = "Comedy" + }, + new + { + Id = (short)2, + Name = "Thriller" + }, + new + { + Id = (short)3, + Name = "Horror" + }, + new + { + Id = (short)4, + Name = "Action" + }, + new + { + Id = (short)5, + Name = "Drama" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Length") + .HasColumnType("smallint"); + + b.Property("MediaPosterImageId") + .HasColumnType("uuid"); + + b.Property("OriginalTitle") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("ReleaseDate") + .HasColumnType("date"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaPosterImageId") + .IsUnique(); + + b.ToTable("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => + { + b.Property("GenreId") + .HasColumnType("smallint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("GenreId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("MediaGenres"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("Budget") + .HasColumnType("money"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaMovies"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.ToTable("MediaPhotoImages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("FirstGradientColor") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("bytea"); + + b.Property("IsUniversalBackground") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("SecondGradientColor") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("bytea"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaPhotoImageBackgrounds"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaPosterImages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => + { + b.Property("CountryId") + .HasColumnType("smallint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("CountryId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("MediaProductionCountries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("HasEnded") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaSeries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IsSpecial") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("MediaSeriesSeasonId") + .HasColumnType("uuid"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesSeasonId"); + + b.ToTable("MediaSeriesEpisodes"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaSeriesId") + .HasColumnType("bigint"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesId"); + + b.ToTable("MediaSeriesSeasons"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BirthDate") + .HasColumnType("date"); + + b.Property("DeathDate") + .HasColumnType("date"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("FullName") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("GenderId") + .HasColumnType("smallint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("PersonPhotoId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("GenderId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonPhotoId") + .IsUnique(); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("PersonActorRoleTypeId") + .HasColumnType("smallint"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.HasIndex("PersonActorRoleTypeId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonActorRoles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRoleType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("PersonActorRoleTypes"); + + b.HasData( + new + { + Id = (short)1, + Name = "Actor" + }, + new + { + Id = (short)2, + Name = "Supporting actor" + }, + new + { + Id = (short)3, + Name = "Voice actor" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("PersonCreatorRoleTypeId") + .HasColumnType("smallint"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.HasIndex("PersonCreatorRoleTypeId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCreatorRoles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRoleType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("PersonCreatorRoleTypes"); + + b.HasData( + new + { + Id = (short)1, + Name = "Director" + }, + new + { + Id = (short)2, + Name = "Producer" + }, + new + { + Id = (short)3, + Name = "Screenwriter" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("PersonPhotoImages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.ToTable("RatingsMedia"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("MediaSeriesEpisodeId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesEpisodeId"); + + b.ToTable("RatingsMediaSeriesEpisode"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("MediaSeriesSeasonId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesSeasonId"); + + b.ToTable("RatingsMediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("PersonActorRoleId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonActorRoleId"); + + b.ToTable("RatingsPersonActorRole", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("PersonCreatorRoleId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonCreatorRoleId"); + + b.ToTable("RatingsPersonCreatorRole", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("date") + .HasDefaultValueSql("now()"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("ViewCount") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasDefaultValue(0L); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.ToTable("ViewCountsMedia", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("date") + .HasDefaultValueSql("now()"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("ViewCount") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasDefaultValue(0L); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonId"); + + b.ToTable("ViewCountsPerson", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "BackgroundPicture") + .WithMany() + .HasForeignKey("BackgroundPictureId"); + + b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") + .WithMany() + .HasForeignKey("GenderId"); + + b.HasOne("WatchIt.Database.Model.Account.AccountProfilePicture", "ProfilePicture") + .WithOne("Account") + .HasForeignKey("WatchIt.Database.Model.Account.Account", "ProfilePictureId"); + + b.Navigation("BackgroundPicture"); + + b.Navigation("Gender"); + + b.Navigation("ProfilePicture"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("AccountRefreshTokens") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaPosterImage", "MediaPosterImage") + .WithOne("Media") + .HasForeignKey("WatchIt.Database.Model.Media.Media", "MediaPosterImageId"); + + b.Navigation("MediaPosterImage"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => + { + b.HasOne("WatchIt.Database.Model.Common.Genre", "Genre") + .WithMany("MediaGenres") + .HasForeignKey("GenreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("MediaGenres") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Genre"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithOne() + .HasForeignKey("WatchIt.Database.Model.Media.MediaMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("MediaPhotoImages") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "MediaPhotoImage") + .WithOne("MediaPhotoImageBackground") + .HasForeignKey("WatchIt.Database.Model.Media.MediaPhotoImageBackground", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaPhotoImage"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => + { + b.HasOne("WatchIt.Database.Model.Common.Country", "Country") + .WithMany("MediaProductionCountries") + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("MediaProductionCountries") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Country"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithOne() + .HasForeignKey("WatchIt.Database.Model.Media.MediaSeries", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") + .WithMany("MediaSeriesEpisodes") + .HasForeignKey("MediaSeriesSeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaSeries", "MediaSeries") + .WithMany("MediaSeriesSeasons") + .HasForeignKey("MediaSeriesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaSeries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => + { + b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") + .WithMany() + .HasForeignKey("GenderId"); + + b.HasOne("WatchIt.Database.Model.Person.PersonPhotoImage", "PersonPhoto") + .WithOne("Person") + .HasForeignKey("WatchIt.Database.Model.Person.Person", "PersonPhotoId"); + + b.Navigation("Gender"); + + b.Navigation("PersonPhoto"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("PersonActorRoles") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonActorRoleType", "PersonActorRoleType") + .WithMany() + .HasForeignKey("PersonActorRoleTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.Person", "Person") + .WithMany("PersonActorRoles") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + + b.Navigation("Person"); + + b.Navigation("PersonActorRoleType"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("PersonCreatorRoles") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRoleType", "PersonCreatorRoleType") + .WithMany() + .HasForeignKey("PersonCreatorRoleTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.Person", "Person") + .WithMany("PersonCreatorRoles") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + + b.Navigation("Person"); + + b.Navigation("PersonCreatorRoleType"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingMedia") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("RatingMedia") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingMediaSeriesEpisode") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.MediaSeriesEpisode", "MediaSeriesEpisode") + .WithMany("RatingMediaSeriesEpisode") + .HasForeignKey("MediaSeriesEpisodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("MediaSeriesEpisode"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingMediaSeriesSeason") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") + .WithMany("RatingMediaSeriesSeason") + .HasForeignKey("MediaSeriesSeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("MediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingPersonActorRole") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonActorRole", "PersonActorRole") + .WithMany("RatingPersonActorRole") + .HasForeignKey("PersonActorRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("PersonActorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingPersonCreatorRole") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRole", "PersonCreatorRole") + .WithMany("RatingPersonCreatorRole") + .HasForeignKey("PersonCreatorRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("PersonCreatorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("ViewCountsMedia") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => + { + b.HasOne("WatchIt.Database.Model.Person.Person", "Person") + .WithMany("ViewCountsPerson") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => + { + b.Navigation("AccountRefreshTokens"); + + b.Navigation("RatingMedia"); + + b.Navigation("RatingMediaSeriesEpisode"); + + b.Navigation("RatingMediaSeriesSeason"); + + b.Navigation("RatingPersonActorRole"); + + b.Navigation("RatingPersonCreatorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => + { + b.Navigation("Account") + .IsRequired(); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => + { + b.Navigation("MediaProductionCountries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => + { + b.Navigation("MediaGenres"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => + { + b.Navigation("MediaGenres"); + + b.Navigation("MediaPhotoImages"); + + b.Navigation("MediaProductionCountries"); + + b.Navigation("PersonActorRoles"); + + b.Navigation("PersonCreatorRoles"); + + b.Navigation("RatingMedia"); + + b.Navigation("ViewCountsMedia"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => + { + b.Navigation("MediaPhotoImageBackground"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => + { + b.Navigation("Media") + .IsRequired(); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => + { + b.Navigation("MediaSeriesSeasons"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => + { + b.Navigation("RatingMediaSeriesEpisode"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => + { + b.Navigation("MediaSeriesEpisodes"); + + b.Navigation("RatingMediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => + { + b.Navigation("PersonActorRoles"); + + b.Navigation("PersonCreatorRoles"); + + b.Navigation("ViewCountsPerson"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => + { + b.Navigation("RatingPersonActorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => + { + b.Navigation("RatingPersonCreatorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => + { + b.Navigation("Person") + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20241108200642_GenreDescriptionRemoved.cs b/WatchIt.Database/WatchIt.Database/Migrations/20241108200642_GenreDescriptionRemoved.cs new file mode 100644 index 0000000..fe1417a --- /dev/null +++ b/WatchIt.Database/WatchIt.Database/Migrations/20241108200642_GenreDescriptionRemoved.cs @@ -0,0 +1,78 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace WatchIt.Database.Migrations +{ + /// + public partial class GenreDescriptionRemoved : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Description", + table: "Genres"); + + migrationBuilder.UpdateData( + table: "Accounts", + keyColumn: "Id", + keyValue: 1L, + columns: new[] { "LeftSalt", "Password", "RightSalt" }, + values: new object[] { "HIZYSU/94oe$[jAy\\{7V", new byte[] { 118, 180, 133, 0, 25, 6, 65, 230, 20, 221, 180, 8, 111, 189, 191, 158, 98, 160, 80, 196, 146, 99, 90, 55, 196, 219, 245, 244, 167, 89, 123, 74, 37, 92, 234, 81, 74, 199, 149, 128, 7, 213, 202, 191, 162, 62, 19, 144, 206, 83, 80, 237, 37, 179, 12, 215, 61, 179, 94, 189, 30, 98, 100, 164 }, "#(^8YBkY; + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Description", + table: "Genres", + type: "character varying(1000)", + maxLength: 1000, + nullable: true); + + migrationBuilder.UpdateData( + table: "Accounts", + keyColumn: "Id", + keyValue: 1L, + columns: new[] { "LeftSalt", "Password", "RightSalt" }, + values: new object[] { "YuJiv1\"R'*0odl8${\\|S", new byte[] { 215, 154, 186, 191, 12, 223, 76, 105, 137, 67, 41, 138, 26, 3, 38, 36, 0, 71, 40, 84, 153, 152, 105, 239, 55, 60, 164, 15, 99, 175, 133, 175, 227, 245, 102, 9, 171, 119, 16, 234, 97, 179, 70, 29, 120, 112, 241, 91, 209, 91, 228, 164, 52, 244, 36, 207, 147, 60, 124, 66, 77, 252, 129, 151 }, "oT2N=y7^5,2o'+N>d}~!" }); + + migrationBuilder.UpdateData( + table: "Genres", + keyColumn: "Id", + keyValue: (short)1, + column: "Description", + value: null); + + migrationBuilder.UpdateData( + table: "Genres", + keyColumn: "Id", + keyValue: (short)2, + column: "Description", + value: null); + + migrationBuilder.UpdateData( + table: "Genres", + keyColumn: "Id", + keyValue: (short)3, + column: "Description", + value: null); + + migrationBuilder.UpdateData( + table: "Genres", + keyColumn: "Id", + keyValue: (short)4, + column: "Description", + value: null); + + migrationBuilder.UpdateData( + table: "Genres", + keyColumn: "Id", + keyValue: (short)5, + column: "Description", + value: null); + } + } +} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20241108211519_AccountFollowAdded.Designer.cs b/WatchIt.Database/WatchIt.Database/Migrations/20241108211519_AccountFollowAdded.Designer.cs new file mode 100644 index 0000000..3a47cb6 --- /dev/null +++ b/WatchIt.Database/WatchIt.Database/Migrations/20241108211519_AccountFollowAdded.Designer.cs @@ -0,0 +1,1459 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using WatchIt.Database; + +#nullable disable + +namespace WatchIt.Database.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20241108211519_AccountFollowAdded")] + partial class AccountFollowAdded + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.5") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true) + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BackgroundPictureId") + .HasColumnType("uuid"); + + b.Property("CreationDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(320) + .HasColumnType("character varying(320)"); + + b.Property("GenderId") + .HasColumnType("smallint"); + + b.Property("IsAdmin") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("LastActive") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("LeftSalt") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("bytea"); + + b.Property("ProfilePictureId") + .HasColumnType("uuid"); + + b.Property("RightSalt") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("BackgroundPictureId"); + + b.HasIndex("GenderId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("ProfilePictureId") + .IsUnique(); + + b.ToTable("Accounts"); + + b.HasData( + new + { + Id = 1L, + CreationDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + Email = "root@watch.it", + IsAdmin = true, + LastActive = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + LeftSalt = "sfA:fW!3D=GbwXn]X+rm", + Password = new byte[] { 95, 134, 48, 126, 85, 131, 129, 152, 252, 161, 69, 133, 62, 112, 45, 111, 3, 163, 80, 99, 167, 66, 169, 121, 140, 69, 242, 14, 89, 126, 184, 43, 62, 87, 22, 1, 88, 246, 34, 181, 231, 110, 14, 54, 120, 114, 37, 67, 240, 82, 112, 125, 84, 155, 194, 90, 14, 189, 90, 68, 30, 146, 204, 105 }, + RightSalt = "@$rr>fSvr5Ls|D+Wp;?D", + Username = "root" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountFollow", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountFollowedId") + .HasColumnType("bigint"); + + b.Property("AccountFollowerId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AccountFollowedId"); + + b.HasIndex("AccountFollowerId"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("AccountFollow"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("AccountProfilePictures"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("IsExtendable") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("AccountRefreshTokens"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsHistorical") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Countries"); + + b.HasData( + new + { + Id = (short)1, + IsHistorical = false, + Name = "Afghanistan" + }, + new + { + Id = (short)2, + IsHistorical = false, + Name = "Albania" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Gender", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Genders"); + + b.HasData( + new + { + Id = (short)1, + Name = "Male" + }, + new + { + Id = (short)2, + Name = "Female" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Genres"); + + b.HasData( + new + { + Id = (short)1, + Name = "Comedy" + }, + new + { + Id = (short)2, + Name = "Thriller" + }, + new + { + Id = (short)3, + Name = "Horror" + }, + new + { + Id = (short)4, + Name = "Action" + }, + new + { + Id = (short)5, + Name = "Drama" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Length") + .HasColumnType("smallint"); + + b.Property("MediaPosterImageId") + .HasColumnType("uuid"); + + b.Property("OriginalTitle") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("ReleaseDate") + .HasColumnType("date"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaPosterImageId") + .IsUnique(); + + b.ToTable("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => + { + b.Property("GenreId") + .HasColumnType("smallint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("GenreId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("MediaGenres"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("Budget") + .HasColumnType("money"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaMovies"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.ToTable("MediaPhotoImages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("FirstGradientColor") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("bytea"); + + b.Property("IsUniversalBackground") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("SecondGradientColor") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("bytea"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaPhotoImageBackgrounds"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaPosterImages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => + { + b.Property("CountryId") + .HasColumnType("smallint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("CountryId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("MediaProductionCountries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("HasEnded") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaSeries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IsSpecial") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("MediaSeriesSeasonId") + .HasColumnType("uuid"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesSeasonId"); + + b.ToTable("MediaSeriesEpisodes"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaSeriesId") + .HasColumnType("bigint"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesId"); + + b.ToTable("MediaSeriesSeasons"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BirthDate") + .HasColumnType("date"); + + b.Property("DeathDate") + .HasColumnType("date"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("FullName") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("GenderId") + .HasColumnType("smallint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("PersonPhotoId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("GenderId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonPhotoId") + .IsUnique(); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("PersonActorRoleTypeId") + .HasColumnType("smallint"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.HasIndex("PersonActorRoleTypeId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonActorRoles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRoleType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("PersonActorRoleTypes"); + + b.HasData( + new + { + Id = (short)1, + Name = "Actor" + }, + new + { + Id = (short)2, + Name = "Supporting actor" + }, + new + { + Id = (short)3, + Name = "Voice actor" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("PersonCreatorRoleTypeId") + .HasColumnType("smallint"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.HasIndex("PersonCreatorRoleTypeId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCreatorRoles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRoleType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("PersonCreatorRoleTypes"); + + b.HasData( + new + { + Id = (short)1, + Name = "Director" + }, + new + { + Id = (short)2, + Name = "Producer" + }, + new + { + Id = (short)3, + Name = "Screenwriter" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("PersonPhotoImages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.ToTable("RatingsMedia"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("MediaSeriesEpisodeId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesEpisodeId"); + + b.ToTable("RatingsMediaSeriesEpisode"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("MediaSeriesSeasonId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesSeasonId"); + + b.ToTable("RatingsMediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("PersonActorRoleId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonActorRoleId"); + + b.ToTable("RatingsPersonActorRole", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("PersonCreatorRoleId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonCreatorRoleId"); + + b.ToTable("RatingsPersonCreatorRole", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("date") + .HasDefaultValueSql("now()"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("ViewCount") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasDefaultValue(0L); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.ToTable("ViewCountsMedia", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("date") + .HasDefaultValueSql("now()"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("ViewCount") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasDefaultValue(0L); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonId"); + + b.ToTable("ViewCountsPerson", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "BackgroundPicture") + .WithMany() + .HasForeignKey("BackgroundPictureId"); + + b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") + .WithMany() + .HasForeignKey("GenderId"); + + b.HasOne("WatchIt.Database.Model.Account.AccountProfilePicture", "ProfilePicture") + .WithOne("Account") + .HasForeignKey("WatchIt.Database.Model.Account.Account", "ProfilePictureId"); + + b.Navigation("BackgroundPicture"); + + b.Navigation("Gender"); + + b.Navigation("ProfilePicture"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountFollow", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "AccountFollowed") + .WithMany("AccountFollowedBy") + .HasForeignKey("AccountFollowedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Account.Account", "AccountFollower") + .WithMany("AccountFollows") + .HasForeignKey("AccountFollowerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccountFollowed"); + + b.Navigation("AccountFollower"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("AccountRefreshTokens") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaPosterImage", "MediaPosterImage") + .WithOne("Media") + .HasForeignKey("WatchIt.Database.Model.Media.Media", "MediaPosterImageId"); + + b.Navigation("MediaPosterImage"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => + { + b.HasOne("WatchIt.Database.Model.Common.Genre", "Genre") + .WithMany("MediaGenres") + .HasForeignKey("GenreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("MediaGenres") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Genre"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithOne() + .HasForeignKey("WatchIt.Database.Model.Media.MediaMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("MediaPhotoImages") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "MediaPhotoImage") + .WithOne("MediaPhotoImageBackground") + .HasForeignKey("WatchIt.Database.Model.Media.MediaPhotoImageBackground", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaPhotoImage"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => + { + b.HasOne("WatchIt.Database.Model.Common.Country", "Country") + .WithMany("MediaProductionCountries") + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("MediaProductionCountries") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Country"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithOne() + .HasForeignKey("WatchIt.Database.Model.Media.MediaSeries", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") + .WithMany("MediaSeriesEpisodes") + .HasForeignKey("MediaSeriesSeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaSeries", "MediaSeries") + .WithMany("MediaSeriesSeasons") + .HasForeignKey("MediaSeriesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaSeries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => + { + b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") + .WithMany() + .HasForeignKey("GenderId"); + + b.HasOne("WatchIt.Database.Model.Person.PersonPhotoImage", "PersonPhoto") + .WithOne("Person") + .HasForeignKey("WatchIt.Database.Model.Person.Person", "PersonPhotoId"); + + b.Navigation("Gender"); + + b.Navigation("PersonPhoto"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("PersonActorRoles") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonActorRoleType", "PersonActorRoleType") + .WithMany() + .HasForeignKey("PersonActorRoleTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.Person", "Person") + .WithMany("PersonActorRoles") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + + b.Navigation("Person"); + + b.Navigation("PersonActorRoleType"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("PersonCreatorRoles") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRoleType", "PersonCreatorRoleType") + .WithMany() + .HasForeignKey("PersonCreatorRoleTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.Person", "Person") + .WithMany("PersonCreatorRoles") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + + b.Navigation("Person"); + + b.Navigation("PersonCreatorRoleType"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingMedia") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("RatingMedia") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingMediaSeriesEpisode") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.MediaSeriesEpisode", "MediaSeriesEpisode") + .WithMany("RatingMediaSeriesEpisode") + .HasForeignKey("MediaSeriesEpisodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("MediaSeriesEpisode"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingMediaSeriesSeason") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") + .WithMany("RatingMediaSeriesSeason") + .HasForeignKey("MediaSeriesSeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("MediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingPersonActorRole") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonActorRole", "PersonActorRole") + .WithMany("RatingPersonActorRole") + .HasForeignKey("PersonActorRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("PersonActorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingPersonCreatorRole") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRole", "PersonCreatorRole") + .WithMany("RatingPersonCreatorRole") + .HasForeignKey("PersonCreatorRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("PersonCreatorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("ViewCountsMedia") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => + { + b.HasOne("WatchIt.Database.Model.Person.Person", "Person") + .WithMany("ViewCountsPerson") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => + { + b.Navigation("AccountFollowedBy"); + + b.Navigation("AccountFollows"); + + b.Navigation("AccountRefreshTokens"); + + b.Navigation("RatingMedia"); + + b.Navigation("RatingMediaSeriesEpisode"); + + b.Navigation("RatingMediaSeriesSeason"); + + b.Navigation("RatingPersonActorRole"); + + b.Navigation("RatingPersonCreatorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => + { + b.Navigation("Account") + .IsRequired(); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => + { + b.Navigation("MediaProductionCountries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => + { + b.Navigation("MediaGenres"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => + { + b.Navigation("MediaGenres"); + + b.Navigation("MediaPhotoImages"); + + b.Navigation("MediaProductionCountries"); + + b.Navigation("PersonActorRoles"); + + b.Navigation("PersonCreatorRoles"); + + b.Navigation("RatingMedia"); + + b.Navigation("ViewCountsMedia"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => + { + b.Navigation("MediaPhotoImageBackground"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => + { + b.Navigation("Media") + .IsRequired(); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => + { + b.Navigation("MediaSeriesSeasons"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => + { + b.Navigation("RatingMediaSeriesEpisode"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => + { + b.Navigation("MediaSeriesEpisodes"); + + b.Navigation("RatingMediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => + { + b.Navigation("PersonActorRoles"); + + b.Navigation("PersonCreatorRoles"); + + b.Navigation("ViewCountsPerson"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => + { + b.Navigation("RatingPersonActorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => + { + b.Navigation("RatingPersonCreatorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => + { + b.Navigation("Person") + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20241108211519_AccountFollowAdded.cs b/WatchIt.Database/WatchIt.Database/Migrations/20241108211519_AccountFollowAdded.cs new file mode 100644 index 0000000..ace5b82 --- /dev/null +++ b/WatchIt.Database/WatchIt.Database/Migrations/20241108211519_AccountFollowAdded.cs @@ -0,0 +1,77 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace WatchIt.Database.Migrations +{ + /// + public partial class AccountFollowAdded : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AccountFollow", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + AccountFollowerId = table.Column(type: "bigint", nullable: false), + AccountFollowedId = table.Column(type: "bigint", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AccountFollow", x => x.Id); + table.ForeignKey( + name: "FK_AccountFollow_Accounts_AccountFollowedId", + column: x => x.AccountFollowedId, + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AccountFollow_Accounts_AccountFollowerId", + column: x => x.AccountFollowerId, + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.UpdateData( + table: "Accounts", + keyColumn: "Id", + keyValue: 1L, + columns: new[] { "LeftSalt", "Password", "RightSalt" }, + values: new object[] { "sfA:fW!3D=GbwXn]X+rm", new byte[] { 95, 134, 48, 126, 85, 131, 129, 152, 252, 161, 69, 133, 62, 112, 45, 111, 3, 163, 80, 99, 167, 66, 169, 121, 140, 69, 242, 14, 89, 126, 184, 43, 62, 87, 22, 1, 88, 246, 34, 181, 231, 110, 14, 54, 120, 114, 37, 67, 240, 82, 112, 125, 84, 155, 194, 90, 14, 189, 90, 68, 30, 146, 204, 105 }, "@$rr>fSvr5Ls|D+Wp;?D" }); + + migrationBuilder.CreateIndex( + name: "IX_AccountFollow_AccountFollowedId", + table: "AccountFollow", + column: "AccountFollowedId"); + + migrationBuilder.CreateIndex( + name: "IX_AccountFollow_AccountFollowerId", + table: "AccountFollow", + column: "AccountFollowerId"); + + migrationBuilder.CreateIndex( + name: "IX_AccountFollow_Id", + table: "AccountFollow", + column: "Id", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AccountFollow"); + + migrationBuilder.UpdateData( + table: "Accounts", + keyColumn: "Id", + keyValue: 1L, + columns: new[] { "LeftSalt", "Password", "RightSalt" }, + values: new object[] { "HIZYSU/94oe$[jAy\\{7V", new byte[] { 118, 180, 133, 0, 25, 6, 65, 230, 20, 221, 180, 8, 111, 189, 191, 158, 98, 160, 80, 196, 146, 99, 90, 55, 196, 219, 245, 244, 167, 89, 123, 74, 37, 92, 234, 81, 74, 199, 149, 128, 7, 213, 202, 191, 162, 62, 19, 144, 206, 83, 80, 237, 37, 179, 12, 215, 61, 179, 94, 189, 30, 98, 100, 164 }, "#(^8YBkY; + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountFollowedId") + .HasColumnType("bigint"); + + b.Property("AccountFollowerId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AccountFollowedId"); + + b.HasIndex("AccountFollowerId"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("AccountFollow"); + }); + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => { b.Property("Id") @@ -249,10 +273,6 @@ namespace WatchIt.Database.Migrations NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - b.Property("Description") - .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); - b.Property("Name") .IsRequired() .HasMaxLength(100) @@ -997,6 +1017,25 @@ namespace WatchIt.Database.Migrations b.Navigation("ProfilePicture"); }); + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountFollow", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "AccountFollowed") + .WithMany("AccountFollowedBy") + .HasForeignKey("AccountFollowedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Account.Account", "AccountFollower") + .WithMany("AccountFollows") + .HasForeignKey("AccountFollowerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccountFollowed"); + + b.Navigation("AccountFollower"); + }); + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => { b.HasOne("WatchIt.Database.Model.Account.Account", "Account") @@ -1309,6 +1348,10 @@ namespace WatchIt.Database.Migrations modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => { + b.Navigation("AccountFollowedBy"); + + b.Navigation("AccountFollows"); + b.Navigation("AccountRefreshTokens"); b.Navigation("RatingMedia"); diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/GenresController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/GenresController.cs index c3f76ff..1b4abc9 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/GenresController.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/GenresController.cs @@ -34,14 +34,6 @@ public class GenresController(IGenresControllerService genresControllerService) [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] public async Task PostGenre([FromBody]GenreRequest body) => await genresControllerService.PostGenre(body); - [HttpPut("{id}")] - [Authorize] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task PutGenre([FromRoute]short id, [FromBody]GenreRequest body) => await genresControllerService.PutGenre(id, body); - [HttpDelete("{id}")] [Authorize] [ProducesResponseType(typeof(GenreResponse), StatusCodes.Status200OK)] diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/GenresControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/GenresControllerService.cs index 0d350dd..3bf88d3 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/GenresControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/GenresControllerService.cs @@ -49,26 +49,6 @@ public class GenresControllerService(DatabaseContext database, IUserService user return RequestResult.Created($"genres/{item.Id}", new GenreResponse(item)); } - public async Task PutGenre(short id, GenreRequest data) - { - UserValidator validator = userService.GetValidator().MustBeAdmin(); - if (!validator.IsValid) - { - return RequestResult.Forbidden(); - } - - Genre? item = await database.Genres.FirstOrDefaultAsync(x => x.Id == id); - if (item is null) - { - return RequestResult.NotFound(); - } - - data.UpdateGenre(item); - await database.SaveChangesAsync(); - - return RequestResult.Ok(); - } - public async Task DeleteGenre(short id) { UserValidator validator = userService.GetValidator().MustBeAdmin(); @@ -98,14 +78,13 @@ public class GenresControllerService(DatabaseContext database, IUserService user public async Task GetGenreMedia(short id, MediaQueryParameters query) { - if (!database.Genres.Any(x => x.Id == id)) + Genre? genre = await database.Genres.FirstOrDefaultAsync(x => x.Id == id); + if (genre is null) { return RequestResult.NotFound(); } - IEnumerable rawData = await database.Media.Where(x => x.MediaGenres.Any(y => y.GenreId == id)) - .ToListAsync(); - IEnumerable data = rawData.Select(x => new MediaResponse(x, database.MediaMovies.Any(y => y.Id == x.Id) ? MediaType.Movie : MediaType.Series)); + IEnumerable data = genre.Media.Select(x => new MediaResponse(x, database.MediaMovies.Any(y => y.Id == x.Id) ? MediaType.Movie : MediaType.Series)); data = query.PrepareData(data); return RequestResult.Ok(data); } diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/IGenresControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/IGenresControllerService.cs index e1a358c..0bc5de9 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/IGenresControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Genres/IGenresControllerService.cs @@ -9,7 +9,6 @@ public interface IGenresControllerService Task GetGenres(GenreQueryParameters query); Task GetGenre(short id); Task PostGenre(GenreRequest data); - Task PutGenre(short id, GenreRequest data); Task DeleteGenre(short id); Task GetGenreMedia(short id, MediaQueryParameters query); } \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Genres/GenreRequestValidator.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Genres/GenreRequestValidator.cs index cf5a9b9..f269793 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Genres/GenreRequestValidator.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Validators/Genres/GenreRequestValidator.cs @@ -9,6 +9,5 @@ public class GenreRequestValidator : AbstractValidator public GenreRequestValidator() { RuleFor(x => x.Name).MaximumLength(100); - When(x => !string.IsNullOrWhiteSpace(x.Description), () => RuleFor(x => x.Description).MaximumLength(1000)); } } \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Genres.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Genres.cs index 1a30507..321c1b5 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Genres.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Genres.cs @@ -6,7 +6,6 @@ public class Genres public string GetGenres { get; set; } public string GetGenre { get; set; } public string PostGenre { get; set; } - public string PutGenre { get; set; } public string DeleteGenre { get; set; } public string GetGenreMedia { get; set; } } \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/appsettings.json b/WatchIt.Website/WatchIt.Website/appsettings.json index 5123a91..72afefa 100644 --- a/WatchIt.Website/WatchIt.Website/appsettings.json +++ b/WatchIt.Website/WatchIt.Website/appsettings.json @@ -49,7 +49,6 @@ "GetGenres": "", "GetGenre": "/{0}", "PostGenre": "", - "PutGenre": "/{0}", "DeleteGenre": "/{0}", "GetGenreMedia": "/{0}/media" }, From 0bf572d84439f6c55aa21513e8e33780aeb306a8 Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Sun, 10 Nov 2024 14:33:41 +0100 Subject: [PATCH 2/2] following added --- .../Account/AccountFollowConfiguration.cs | 2 +- .../WatchIt.Database.Model/Account/Account.cs | 2 +- .../WatchIt.Database/DatabaseContext.cs | 1 + .../20241109182449_RelationRename.Designer.cs | 1459 +++++++++++++++++ .../20241109182449_RelationRename.cs | 136 ++ .../DatabaseContextModelSnapshot.cs | 12 +- .../AccountsController.cs | 33 + .../AccountsControllerService.cs | 75 + .../IAccountsControllerService.cs | 4 + .../Accounts/AccountsClientService.cs | 125 +- .../Accounts/IAccountsClientService.cs | 12 +- .../Model/Accounts.cs | 4 + WatchIt.Website/WatchIt.Website/App.razor | 2 +- .../UserListItemComponent.razor} | 2 +- .../UserListItemComponent.razor.cs} | 5 +- .../UsersSearchResultPanelComponent.razor | 3 +- .../Panels/FollowListPanelComponent.razor | 29 + .../Panels/FollowListPanelComponent.razor.cs | 41 + .../Panels/UserPageHeaderPanelComponent.razor | 40 +- .../UserPageHeaderPanelComponent.razor.cs | 48 +- .../WatchIt.Website/Pages/UserPage.razor | 40 +- .../WatchIt.Website/Pages/UserPage.razor.cs | 19 +- .../WatchIt.Website/appsettings.json | 6 +- .../WatchIt.Website/wwwroot/css/general.css | 5 + 24 files changed, 2015 insertions(+), 90 deletions(-) create mode 100644 WatchIt.Database/WatchIt.Database/Migrations/20241109182449_RelationRename.Designer.cs create mode 100644 WatchIt.Database/WatchIt.Database/Migrations/20241109182449_RelationRename.cs rename WatchIt.Website/WatchIt.Website/Components/{Pages/SearchPage/Subcomponents/UserSearchResultItemComponent.razor => Common/Subcomponents/UserListItemComponent.razor} (80%) rename WatchIt.Website/WatchIt.Website/Components/{Pages/SearchPage/Subcomponents/UserSearchResultItemComponent.razor.cs => Common/Subcomponents/UserListItemComponent.razor.cs} (51%) create mode 100644 WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/FollowListPanelComponent.razor create mode 100644 WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/FollowListPanelComponent.razor.cs diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountFollowConfiguration.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountFollowConfiguration.cs index 18f237e..89d1bf2 100644 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountFollowConfiguration.cs +++ b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model.Configuration/Account/AccountFollowConfiguration.cs @@ -22,7 +22,7 @@ public class AccountFollowConfiguration : IEntityTypeConfiguration x.AccountFollowed) - .WithMany(x => x.AccountFollowedBy) + .WithMany(x => x.AccountFollowers) .HasForeignKey(x => x.AccountFollowedId) .IsRequired(); builder.Property(x => x.AccountFollowedId) diff --git a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs index 181dd59..227a740 100644 --- a/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs +++ b/WatchIt.Database/WatchIt.Database.Model/WatchIt.Database.Model/Account/Account.cs @@ -41,7 +41,7 @@ public class Account public virtual IEnumerable AccountRefreshTokens { get; set; } = new List(); public virtual IEnumerable AccountFollows { get; set; } = new List(); - public virtual IEnumerable AccountFollowedBy { get; set; } = new List(); + public virtual IEnumerable AccountFollowers { get; set; } = new List(); #endregion } \ No newline at end of file diff --git a/WatchIt.Database/WatchIt.Database/DatabaseContext.cs b/WatchIt.Database/WatchIt.Database/DatabaseContext.cs index d04598f..790dc64 100644 --- a/WatchIt.Database/WatchIt.Database/DatabaseContext.cs +++ b/WatchIt.Database/WatchIt.Database/DatabaseContext.cs @@ -40,6 +40,7 @@ public class DatabaseContext : DbContext // Account public virtual DbSet Accounts { get; set; } + public virtual DbSet AccountFollows { get; set; } public virtual DbSet AccountProfilePictures { get; set; } public virtual DbSet AccountRefreshTokens { get; set; } diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20241109182449_RelationRename.Designer.cs b/WatchIt.Database/WatchIt.Database/Migrations/20241109182449_RelationRename.Designer.cs new file mode 100644 index 0000000..eb8af24 --- /dev/null +++ b/WatchIt.Database/WatchIt.Database/Migrations/20241109182449_RelationRename.Designer.cs @@ -0,0 +1,1459 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using WatchIt.Database; + +#nullable disable + +namespace WatchIt.Database.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20241109182449_RelationRename")] + partial class RelationRename + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.5") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true) + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BackgroundPictureId") + .HasColumnType("uuid"); + + b.Property("CreationDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(320) + .HasColumnType("character varying(320)"); + + b.Property("GenderId") + .HasColumnType("smallint"); + + b.Property("IsAdmin") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("LastActive") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("LeftSalt") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("bytea"); + + b.Property("ProfilePictureId") + .HasColumnType("uuid"); + + b.Property("RightSalt") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("BackgroundPictureId"); + + b.HasIndex("GenderId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("ProfilePictureId") + .IsUnique(); + + b.ToTable("Accounts"); + + b.HasData( + new + { + Id = 1L, + CreationDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + Email = "root@watch.it", + IsAdmin = true, + LastActive = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + LeftSalt = "QkJky0:m43g!mRL_-0S'", + Password = new byte[] { 104, 21, 33, 198, 192, 7, 229, 80, 195, 46, 190, 26, 125, 243, 113, 195, 194, 9, 145, 142, 56, 34, 125, 141, 133, 113, 14, 172, 29, 90, 194, 60, 98, 40, 121, 132, 218, 157, 80, 128, 70, 136, 201, 208, 36, 37, 124, 215, 144, 242, 212, 68, 209, 27, 248, 191, 212, 84, 250, 35, 230, 51, 218, 15 }, + RightSalt = "~-jO$aMa{Q9lAW~>)Z+Z", + Username = "root" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountFollow", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountFollowedId") + .HasColumnType("bigint"); + + b.Property("AccountFollowerId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AccountFollowedId"); + + b.HasIndex("AccountFollowerId"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("AccountFollows"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("AccountProfilePictures"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("IsExtendable") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("AccountRefreshTokens"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsHistorical") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Countries"); + + b.HasData( + new + { + Id = (short)1, + IsHistorical = false, + Name = "Afghanistan" + }, + new + { + Id = (short)2, + IsHistorical = false, + Name = "Albania" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Gender", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Genders"); + + b.HasData( + new + { + Id = (short)1, + Name = "Male" + }, + new + { + Id = (short)2, + Name = "Female" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("Genres"); + + b.HasData( + new + { + Id = (short)1, + Name = "Comedy" + }, + new + { + Id = (short)2, + Name = "Thriller" + }, + new + { + Id = (short)3, + Name = "Horror" + }, + new + { + Id = (short)4, + Name = "Action" + }, + new + { + Id = (short)5, + Name = "Drama" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Length") + .HasColumnType("smallint"); + + b.Property("MediaPosterImageId") + .HasColumnType("uuid"); + + b.Property("OriginalTitle") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("ReleaseDate") + .HasColumnType("date"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaPosterImageId") + .IsUnique(); + + b.ToTable("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => + { + b.Property("GenreId") + .HasColumnType("smallint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("GenreId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("MediaGenres"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("Budget") + .HasColumnType("money"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaMovies"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.ToTable("MediaPhotoImages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("FirstGradientColor") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("bytea"); + + b.Property("IsUniversalBackground") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("SecondGradientColor") + .IsRequired() + .HasMaxLength(3) + .HasColumnType("bytea"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaPhotoImageBackgrounds"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaPosterImages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => + { + b.Property("CountryId") + .HasColumnType("smallint"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.HasKey("CountryId", "MediaId"); + + b.HasIndex("MediaId"); + + b.ToTable("MediaProductionCountries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("HasEnded") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("MediaSeries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IsSpecial") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("MediaSeriesSeasonId") + .HasColumnType("uuid"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesSeasonId"); + + b.ToTable("MediaSeriesEpisodes"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaSeriesId") + .HasColumnType("bigint"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesId"); + + b.ToTable("MediaSeriesSeasons"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BirthDate") + .HasColumnType("date"); + + b.Property("DeathDate") + .HasColumnType("date"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("FullName") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("GenderId") + .HasColumnType("smallint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("PersonPhotoId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("GenderId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonPhotoId") + .IsUnique(); + + b.ToTable("Persons"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("PersonActorRoleTypeId") + .HasColumnType("smallint"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.HasIndex("PersonActorRoleTypeId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonActorRoles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRoleType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("PersonActorRoleTypes"); + + b.HasData( + new + { + Id = (short)1, + Name = "Actor" + }, + new + { + Id = (short)2, + Name = "Supporting actor" + }, + new + { + Id = (short)3, + Name = "Voice actor" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("PersonCreatorRoleTypeId") + .HasColumnType("smallint"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.HasIndex("PersonCreatorRoleTypeId"); + + b.HasIndex("PersonId"); + + b.ToTable("PersonCreatorRoles"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRoleType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("smallint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("PersonCreatorRoleTypes"); + + b.HasData( + new + { + Id = (short)1, + Name = "Director" + }, + new + { + Id = (short)2, + Name = "Producer" + }, + new + { + Id = (short)3, + Name = "Screenwriter" + }); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Image") + .IsRequired() + .HasMaxLength(-1) + .HasColumnType("bytea"); + + b.Property("MimeType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("UploadDate") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.ToTable("PersonPhotoImages"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.ToTable("RatingsMedia"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("MediaSeriesEpisodeId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesEpisodeId"); + + b.ToTable("RatingsMediaSeriesEpisode"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("MediaSeriesSeasonId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaSeriesSeasonId"); + + b.ToTable("RatingsMediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("PersonActorRoleId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonActorRoleId"); + + b.ToTable("RatingsPersonActorRole", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("bigint"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone") + .HasDefaultValueSql("now()"); + + b.Property("PersonCreatorRoleId") + .HasColumnType("uuid"); + + b.Property("Rating") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonCreatorRoleId"); + + b.ToTable("RatingsPersonCreatorRole", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("date") + .HasDefaultValueSql("now()"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("ViewCount") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasDefaultValue(0L); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("MediaId"); + + b.ToTable("ViewCountsMedia", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Date") + .ValueGeneratedOnAdd() + .HasColumnType("date") + .HasDefaultValueSql("now()"); + + b.Property("PersonId") + .HasColumnType("bigint"); + + b.Property("ViewCount") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasDefaultValue(0L); + + b.HasKey("Id"); + + b.HasIndex("Id") + .IsUnique(); + + b.HasIndex("PersonId"); + + b.ToTable("ViewCountsPerson", (string)null); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "BackgroundPicture") + .WithMany() + .HasForeignKey("BackgroundPictureId"); + + b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") + .WithMany() + .HasForeignKey("GenderId"); + + b.HasOne("WatchIt.Database.Model.Account.AccountProfilePicture", "ProfilePicture") + .WithOne("Account") + .HasForeignKey("WatchIt.Database.Model.Account.Account", "ProfilePictureId"); + + b.Navigation("BackgroundPicture"); + + b.Navigation("Gender"); + + b.Navigation("ProfilePicture"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountFollow", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "AccountFollowed") + .WithMany("AccountFollowers") + .HasForeignKey("AccountFollowedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Account.Account", "AccountFollower") + .WithMany("AccountFollows") + .HasForeignKey("AccountFollowerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccountFollowed"); + + b.Navigation("AccountFollower"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountRefreshToken", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("AccountRefreshTokens") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaPosterImage", "MediaPosterImage") + .WithOne("Media") + .HasForeignKey("WatchIt.Database.Model.Media.Media", "MediaPosterImageId"); + + b.Navigation("MediaPosterImage"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaGenre", b => + { + b.HasOne("WatchIt.Database.Model.Common.Genre", "Genre") + .WithMany("MediaGenres") + .HasForeignKey("GenreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("MediaGenres") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Genre"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaMovie", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithOne() + .HasForeignKey("WatchIt.Database.Model.Media.MediaMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("MediaPhotoImages") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImageBackground", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaPhotoImage", "MediaPhotoImage") + .WithOne("MediaPhotoImageBackground") + .HasForeignKey("WatchIt.Database.Model.Media.MediaPhotoImageBackground", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaPhotoImage"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaProductionCountry", b => + { + b.HasOne("WatchIt.Database.Model.Common.Country", "Country") + .WithMany("MediaProductionCountries") + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("MediaProductionCountries") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Country"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithOne() + .HasForeignKey("WatchIt.Database.Model.Media.MediaSeries", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") + .WithMany("MediaSeriesEpisodes") + .HasForeignKey("MediaSeriesSeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => + { + b.HasOne("WatchIt.Database.Model.Media.MediaSeries", "MediaSeries") + .WithMany("MediaSeriesSeasons") + .HasForeignKey("MediaSeriesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaSeries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => + { + b.HasOne("WatchIt.Database.Model.Common.Gender", "Gender") + .WithMany() + .HasForeignKey("GenderId"); + + b.HasOne("WatchIt.Database.Model.Person.PersonPhotoImage", "PersonPhoto") + .WithOne("Person") + .HasForeignKey("WatchIt.Database.Model.Person.Person", "PersonPhotoId"); + + b.Navigation("Gender"); + + b.Navigation("PersonPhoto"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("PersonActorRoles") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonActorRoleType", "PersonActorRoleType") + .WithMany() + .HasForeignKey("PersonActorRoleTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.Person", "Person") + .WithMany("PersonActorRoles") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + + b.Navigation("Person"); + + b.Navigation("PersonActorRoleType"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("PersonCreatorRoles") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRoleType", "PersonCreatorRoleType") + .WithMany() + .HasForeignKey("PersonCreatorRoleTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.Person", "Person") + .WithMany("PersonCreatorRoles") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + + b.Navigation("Person"); + + b.Navigation("PersonCreatorRoleType"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMedia", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingMedia") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("RatingMedia") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesEpisode", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingMediaSeriesEpisode") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.MediaSeriesEpisode", "MediaSeriesEpisode") + .WithMany("RatingMediaSeriesEpisode") + .HasForeignKey("MediaSeriesEpisodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("MediaSeriesEpisode"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingMediaSeriesSeason", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingMediaSeriesSeason") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Media.MediaSeriesSeason", "MediaSeriesSeason") + .WithMany("RatingMediaSeriesSeason") + .HasForeignKey("MediaSeriesSeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("MediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonActorRole", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingPersonActorRole") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonActorRole", "PersonActorRole") + .WithMany("RatingPersonActorRole") + .HasForeignKey("PersonActorRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("PersonActorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Rating.RatingPersonCreatorRole", b => + { + b.HasOne("WatchIt.Database.Model.Account.Account", "Account") + .WithMany("RatingPersonCreatorRole") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("WatchIt.Database.Model.Person.PersonCreatorRole", "PersonCreatorRole") + .WithMany("RatingPersonCreatorRole") + .HasForeignKey("PersonCreatorRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("PersonCreatorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountMedia", b => + { + b.HasOne("WatchIt.Database.Model.Media.Media", "Media") + .WithMany("ViewCountsMedia") + .HasForeignKey("MediaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Media"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.ViewCount.ViewCountPerson", b => + { + b.HasOne("WatchIt.Database.Model.Person.Person", "Person") + .WithMany("ViewCountsPerson") + .HasForeignKey("PersonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Person"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => + { + b.Navigation("AccountFollowers"); + + b.Navigation("AccountFollows"); + + b.Navigation("AccountRefreshTokens"); + + b.Navigation("RatingMedia"); + + b.Navigation("RatingMediaSeriesEpisode"); + + b.Navigation("RatingMediaSeriesSeason"); + + b.Navigation("RatingPersonActorRole"); + + b.Navigation("RatingPersonCreatorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => + { + b.Navigation("Account") + .IsRequired(); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Country", b => + { + b.Navigation("MediaProductionCountries"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Common.Genre", b => + { + b.Navigation("MediaGenres"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.Media", b => + { + b.Navigation("MediaGenres"); + + b.Navigation("MediaPhotoImages"); + + b.Navigation("MediaProductionCountries"); + + b.Navigation("PersonActorRoles"); + + b.Navigation("PersonCreatorRoles"); + + b.Navigation("RatingMedia"); + + b.Navigation("ViewCountsMedia"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPhotoImage", b => + { + b.Navigation("MediaPhotoImageBackground"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaPosterImage", b => + { + b.Navigation("Media") + .IsRequired(); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeries", b => + { + b.Navigation("MediaSeriesSeasons"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesEpisode", b => + { + b.Navigation("RatingMediaSeriesEpisode"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Media.MediaSeriesSeason", b => + { + b.Navigation("MediaSeriesEpisodes"); + + b.Navigation("RatingMediaSeriesSeason"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.Person", b => + { + b.Navigation("PersonActorRoles"); + + b.Navigation("PersonCreatorRoles"); + + b.Navigation("ViewCountsPerson"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonActorRole", b => + { + b.Navigation("RatingPersonActorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonCreatorRole", b => + { + b.Navigation("RatingPersonCreatorRole"); + }); + + modelBuilder.Entity("WatchIt.Database.Model.Person.PersonPhotoImage", b => + { + b.Navigation("Person") + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/20241109182449_RelationRename.cs b/WatchIt.Database/WatchIt.Database/Migrations/20241109182449_RelationRename.cs new file mode 100644 index 0000000..6c093ea --- /dev/null +++ b/WatchIt.Database/WatchIt.Database/Migrations/20241109182449_RelationRename.cs @@ -0,0 +1,136 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace WatchIt.Database.Migrations +{ + /// + public partial class RelationRename : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AccountFollow_Accounts_AccountFollowedId", + table: "AccountFollow"); + + migrationBuilder.DropForeignKey( + name: "FK_AccountFollow_Accounts_AccountFollowerId", + table: "AccountFollow"); + + migrationBuilder.DropPrimaryKey( + name: "PK_AccountFollow", + table: "AccountFollow"); + + migrationBuilder.RenameTable( + name: "AccountFollow", + newName: "AccountFollows"); + + migrationBuilder.RenameIndex( + name: "IX_AccountFollow_Id", + table: "AccountFollows", + newName: "IX_AccountFollows_Id"); + + migrationBuilder.RenameIndex( + name: "IX_AccountFollow_AccountFollowerId", + table: "AccountFollows", + newName: "IX_AccountFollows_AccountFollowerId"); + + migrationBuilder.RenameIndex( + name: "IX_AccountFollow_AccountFollowedId", + table: "AccountFollows", + newName: "IX_AccountFollows_AccountFollowedId"); + + migrationBuilder.AddPrimaryKey( + name: "PK_AccountFollows", + table: "AccountFollows", + column: "Id"); + + migrationBuilder.UpdateData( + table: "Accounts", + keyColumn: "Id", + keyValue: 1L, + columns: new[] { "LeftSalt", "Password", "RightSalt" }, + values: new object[] { "QkJky0:m43g!mRL_-0S'", new byte[] { 104, 21, 33, 198, 192, 7, 229, 80, 195, 46, 190, 26, 125, 243, 113, 195, 194, 9, 145, 142, 56, 34, 125, 141, 133, 113, 14, 172, 29, 90, 194, 60, 98, 40, 121, 132, 218, 157, 80, 128, 70, 136, 201, 208, 36, 37, 124, 215, 144, 242, 212, 68, 209, 27, 248, 191, 212, 84, 250, 35, 230, 51, 218, 15 }, "~-jO$aMa{Q9lAW~>)Z+Z" }); + + migrationBuilder.AddForeignKey( + name: "FK_AccountFollows_Accounts_AccountFollowedId", + table: "AccountFollows", + column: "AccountFollowedId", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_AccountFollows_Accounts_AccountFollowerId", + table: "AccountFollows", + column: "AccountFollowerId", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AccountFollows_Accounts_AccountFollowedId", + table: "AccountFollows"); + + migrationBuilder.DropForeignKey( + name: "FK_AccountFollows_Accounts_AccountFollowerId", + table: "AccountFollows"); + + migrationBuilder.DropPrimaryKey( + name: "PK_AccountFollows", + table: "AccountFollows"); + + migrationBuilder.RenameTable( + name: "AccountFollows", + newName: "AccountFollow"); + + migrationBuilder.RenameIndex( + name: "IX_AccountFollows_Id", + table: "AccountFollow", + newName: "IX_AccountFollow_Id"); + + migrationBuilder.RenameIndex( + name: "IX_AccountFollows_AccountFollowerId", + table: "AccountFollow", + newName: "IX_AccountFollow_AccountFollowerId"); + + migrationBuilder.RenameIndex( + name: "IX_AccountFollows_AccountFollowedId", + table: "AccountFollow", + newName: "IX_AccountFollow_AccountFollowedId"); + + migrationBuilder.AddPrimaryKey( + name: "PK_AccountFollow", + table: "AccountFollow", + column: "Id"); + + migrationBuilder.UpdateData( + table: "Accounts", + keyColumn: "Id", + keyValue: 1L, + columns: new[] { "LeftSalt", "Password", "RightSalt" }, + values: new object[] { "sfA:fW!3D=GbwXn]X+rm", new byte[] { 95, 134, 48, 126, 85, 131, 129, 152, 252, 161, 69, 133, 62, 112, 45, 111, 3, 163, 80, 99, 167, 66, 169, 121, 140, 69, 242, 14, 89, 126, 184, 43, 62, 87, 22, 1, 88, 246, 34, 181, 231, 110, 14, 54, 120, 114, 37, 67, 240, 82, 112, 125, 84, 155, 194, 90, 14, 189, 90, 68, 30, 146, 204, 105 }, "@$rr>fSvr5Ls|D+Wp;?D" }); + + migrationBuilder.AddForeignKey( + name: "FK_AccountFollow_Accounts_AccountFollowedId", + table: "AccountFollow", + column: "AccountFollowedId", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_AccountFollow_Accounts_AccountFollowerId", + table: "AccountFollow", + column: "AccountFollowerId", + principalTable: "Accounts", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/WatchIt.Database/WatchIt.Database/Migrations/DatabaseContextModelSnapshot.cs b/WatchIt.Database/WatchIt.Database/Migrations/DatabaseContextModelSnapshot.cs index a388421..d0c9b33 100644 --- a/WatchIt.Database/WatchIt.Database/Migrations/DatabaseContextModelSnapshot.cs +++ b/WatchIt.Database/WatchIt.Database/Migrations/DatabaseContextModelSnapshot.cs @@ -108,9 +108,9 @@ namespace WatchIt.Database.Migrations Email = "root@watch.it", IsAdmin = true, LastActive = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - LeftSalt = "sfA:fW!3D=GbwXn]X+rm", - Password = new byte[] { 95, 134, 48, 126, 85, 131, 129, 152, 252, 161, 69, 133, 62, 112, 45, 111, 3, 163, 80, 99, 167, 66, 169, 121, 140, 69, 242, 14, 89, 126, 184, 43, 62, 87, 22, 1, 88, 246, 34, 181, 231, 110, 14, 54, 120, 114, 37, 67, 240, 82, 112, 125, 84, 155, 194, 90, 14, 189, 90, 68, 30, 146, 204, 105 }, - RightSalt = "@$rr>fSvr5Ls|D+Wp;?D", + LeftSalt = "QkJky0:m43g!mRL_-0S'", + Password = new byte[] { 104, 21, 33, 198, 192, 7, 229, 80, 195, 46, 190, 26, 125, 243, 113, 195, 194, 9, 145, 142, 56, 34, 125, 141, 133, 113, 14, 172, 29, 90, 194, 60, 98, 40, 121, 132, 218, 157, 80, 128, 70, 136, 201, 208, 36, 37, 124, 215, 144, 242, 212, 68, 209, 27, 248, 191, 212, 84, 250, 35, 230, 51, 218, 15 }, + RightSalt = "~-jO$aMa{Q9lAW~>)Z+Z", Username = "root" }); }); @@ -136,7 +136,7 @@ namespace WatchIt.Database.Migrations b.HasIndex("Id") .IsUnique(); - b.ToTable("AccountFollow"); + b.ToTable("AccountFollows"); }); modelBuilder.Entity("WatchIt.Database.Model.Account.AccountProfilePicture", b => @@ -1020,7 +1020,7 @@ namespace WatchIt.Database.Migrations modelBuilder.Entity("WatchIt.Database.Model.Account.AccountFollow", b => { b.HasOne("WatchIt.Database.Model.Account.Account", "AccountFollowed") - .WithMany("AccountFollowedBy") + .WithMany("AccountFollowers") .HasForeignKey("AccountFollowedId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -1348,7 +1348,7 @@ namespace WatchIt.Database.Migrations modelBuilder.Entity("WatchIt.Database.Model.Account.Account", b => { - b.Navigation("AccountFollowedBy"); + b.Navigation("AccountFollowers"); b.Navigation("AccountFollows"); diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs index a57a424..e556d81 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs @@ -135,6 +135,8 @@ public class AccountsController(IAccountsControllerService accountsControllerSer #endregion + #region Media + [HttpGet("{id}/movies")] [AllowAnonymous] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] @@ -152,4 +154,35 @@ public class AccountsController(IAccountsControllerService accountsControllerSer [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetAccountRatedPersons([FromRoute]long id, PersonRatedQueryParameters query) => await accountsControllerService.GetAccountRatedPersons(id, query); + + #endregion + + #region Follows + + [HttpGet("{id}/follows")] + [AllowAnonymous] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetAccountFollows([FromRoute]long id, AccountQueryParameters query) => await accountsControllerService.GetAccountFollows(id, query); + + [HttpGet("{id}/followers")] + [AllowAnonymous] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetAccountFollowers([FromRoute]long id, AccountQueryParameters query) => await accountsControllerService.GetAccountFollowers(id, query); + + [HttpPost("follows/{user_id}")] + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + public async Task PostAccountFollow([FromRoute(Name = "user_id")]long userId) => await accountsControllerService.PostAccountFollow(userId); + + [HttpDelete("follows/{user_id}")] + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] + public async Task DeleteAccountFollow([FromRoute(Name = "user_id")]long userId) => await accountsControllerService.DeleteAccountFollow(userId); + + #endregion } \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs index 14fc4ba..b6c75c6 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs @@ -319,6 +319,8 @@ public class AccountsControllerService( #endregion + #region Media + public async Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query) { Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id); @@ -362,6 +364,79 @@ public class AccountsControllerService( response = query.PrepareData(response); return RequestResult.Ok(response); } + + #endregion + + #region Follows + + public async Task GetAccountFollows(long id, AccountQueryParameters query) + { + Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id); + if (account is null) + { + return RequestResult.NotFound(); + } + + IEnumerable data = account.AccountFollows.Select(x => new AccountResponse(x.AccountFollowed)); + data = query.PrepareData(data); + return RequestResult.Ok(data); + } + + public async Task GetAccountFollowers(long id, AccountQueryParameters query) + { + Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id); + if (account is null) + { + return RequestResult.NotFound(); + } + + IEnumerable data = account.AccountFollowers.Select(x => new AccountResponse(x.AccountFollower)); + data = query.PrepareData(data); + return RequestResult.Ok(data); + } + + public async Task PostAccountFollow(long userId) + { + long followerId = userService.GetUserId(); + if (userId == followerId) + { + return RequestResult.BadRequest().AddValidationError("user_id", "You cannot follow yourself"); + } + if (!database.Accounts.Any(x => x.Id == userId)) + { + return RequestResult.BadRequest().AddValidationError("user_id", "User with this id doesn't exist"); + } + + Account account = await database.Accounts.FirstAsync(x => x.Id == followerId); + if (account.AccountFollows.All(x => x.AccountFollowedId != userId)) + { + AccountFollow follow = new AccountFollow() + { + AccountFollowerId = followerId, + AccountFollowedId = userId, + }; + await database.AccountFollows.AddAsync(follow); + await database.SaveChangesAsync(); + } + + return RequestResult.Ok(); + } + + public async Task DeleteAccountFollow(long userId) + { + AccountFollow? accountFollow = await database.AccountFollows.FirstOrDefaultAsync(x => x.AccountFollowerId == userService.GetUserId() && x.AccountFollowedId == userId); + + if (accountFollow is not null) + { + database.AccountFollows.Attach(accountFollow); + database.AccountFollows.Remove(accountFollow); + await database.SaveChangesAsync(); + } + + return RequestResult.Ok(); + } + + #endregion #endregion diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs index bb03dc5..9e51d77 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs @@ -28,4 +28,8 @@ public interface IAccountsControllerService Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query); Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters query); Task GetAccountRatedPersons(long id, PersonRatedQueryParameters query); + Task GetAccountFollows(long id, AccountQueryParameters query); + Task GetAccountFollowers(long id, AccountQueryParameters query); + Task PostAccountFollow(long userId); + Task DeleteAccountFollow(long userId); } \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/AccountsClientService.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/AccountsClientService.cs index df8649f..0be0807 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/AccountsClientService.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/AccountsClientService.cs @@ -13,6 +13,36 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig { #region PUBLIC METHODS + #region Main + + public async Task GetAccounts(AccountQueryParameters? query = null, Action>? successAction = null) + { + string url = GetUrl(EndpointsConfiguration.Accounts.GetAccounts); + HttpRequest request = new HttpRequest(HttpMethodType.Get, url) + { + Query = query + }; + + HttpResponse response = await httpClientService.SendRequestAsync(request); + response.RegisterActionFor2XXSuccess(successAction) + .ExecuteAction(); + } + + public async Task GetAccount(long id, Action? successAction = null, Action? notFoundAction = null) + { + string url = GetUrl(EndpointsConfiguration.Accounts.GetAccount, id); + HttpRequest request = new HttpRequest(HttpMethodType.Get, url); + + HttpResponse response = await httpClientService.SendRequestAsync(request); + response.RegisterActionFor2XXSuccess(successAction) + .RegisterActionFor404NotFound(notFoundAction) + .ExecuteAction(); + } + + #endregion + + #region Authentication + public async Task Register(RegisterRequest data, Action? createdAction = null, Action>? badRequestAction = null) { string url = GetUrl(EndpointsConfiguration.Accounts.Register); @@ -69,7 +99,11 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig response.RegisterActionFor2XXSuccess(successAction) .ExecuteAction(); } + + #endregion + #region Profile picture + public async Task GetAccountProfilePicture(long id, Action? successAction = null, Action>? badRequestAction = null, Action? notFoundAction = null) { string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountProfilePicture, id); @@ -109,7 +143,11 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig .RegisterActionFor401Unauthorized(unauthorizedAction) .ExecuteAction(); } - + + #endregion + + #region Profile background + public async Task GetAccountProfileBackground(long id, Action? successAction = null, Action>? badRequestAction = null, Action? notFoundAction = null) { string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountProfileBackground, id); @@ -150,29 +188,9 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig .ExecuteAction(); } - public async Task GetAccounts(AccountQueryParameters query, Action>? successAction = null) - { - string url = GetUrl(EndpointsConfiguration.Accounts.GetAccounts); - HttpRequest request = new HttpRequest(HttpMethodType.Get, url) - { - Query = query - }; - - HttpResponse response = await httpClientService.SendRequestAsync(request); - response.RegisterActionFor2XXSuccess(successAction) - .ExecuteAction(); - } + #endregion - public async Task GetAccount(long id, Action? successAction = null, Action? notFoundAction = null) - { - string url = GetUrl(EndpointsConfiguration.Accounts.GetAccount, id); - HttpRequest request = new HttpRequest(HttpMethodType.Get, url); - - HttpResponse response = await httpClientService.SendRequestAsync(request); - response.RegisterActionFor2XXSuccess(successAction) - .RegisterActionFor404NotFound(notFoundAction) - .ExecuteAction(); - } + #region Account management public async Task PutAccountProfileInfo(AccountProfileInfoRequest data, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null) { @@ -234,6 +252,10 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig .ExecuteAction(); } + #endregion + + #region Media + public async Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query, Action>? successAction = null, Action? notFoundAction = null) { string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountRatedMovies, id); @@ -275,6 +297,63 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig .RegisterActionFor404NotFound(notFoundAction) .ExecuteAction(); } + + #endregion + + #region Follows + + public async Task GetAccountFollows(long id, AccountQueryParameters? query = null, Action>? successAction = null, Action? notFoundAction = null) + { + string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountFollows, id); + HttpRequest request = new HttpRequest(HttpMethodType.Get, url) + { + Query = query + }; + + HttpResponse response = await httpClientService.SendRequestAsync(request); + response.RegisterActionFor2XXSuccess(successAction) + .RegisterActionFor404NotFound(notFoundAction) + .ExecuteAction(); + } + + public async Task GetAccountFollowers(long id, AccountQueryParameters? query = null, Action>? successAction = null, Action? notFoundAction = null) + { + string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountFollowers, id); + HttpRequest request = new HttpRequest(HttpMethodType.Get, url) + { + Query = query + }; + + HttpResponse response = await httpClientService.SendRequestAsync(request); + response.RegisterActionFor2XXSuccess(successAction) + .RegisterActionFor404NotFound(notFoundAction) + .ExecuteAction(); + } + + public async Task PostAccountFollow(long userId, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null) + { + string url = GetUrl(EndpointsConfiguration.Accounts.PostAccountFollow, userId); + HttpRequest request = new HttpRequest(HttpMethodType.Post, url); + + HttpResponse response = await httpClientService.SendRequestAsync(request); + response.RegisterActionFor2XXSuccess(successAction) + .RegisterActionFor400BadRequest(badRequestAction) + .RegisterActionFor401Unauthorized(unauthorizedAction) + .ExecuteAction(); + } + + public async Task DeleteAccountFollow(long userId, Action? successAction = null, Action? unauthorizedAction = null) + { + string url = GetUrl(EndpointsConfiguration.Accounts.DeleteAccountFollow, userId); + HttpRequest request = new HttpRequest(HttpMethodType.Delete, url); + + HttpResponse response = await httpClientService.SendRequestAsync(request); + response.RegisterActionFor2XXSuccess(successAction) + .RegisterActionFor401Unauthorized(unauthorizedAction) + .ExecuteAction(); + } + + #endregion #endregion diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/IAccountsClientService.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/IAccountsClientService.cs index 09543c6..7300a14 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/IAccountsClientService.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/IAccountsClientService.cs @@ -18,13 +18,17 @@ public interface IAccountsClientService Task GetAccountProfileBackground(long id, Action? successAction = null, Action>? badRequestAction = null, Action? notFoundAction = null); Task PutAccountProfileBackground(AccountProfileBackgroundRequest data, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null); Task DeleteAccountProfileBackground(Action? successAction = null, Action? unauthorizedAction = null); - Task GetAccounts(AccountQueryParameters query, Action>? successAction = null); + Task GetAccounts(AccountQueryParameters? query = null, Action>? successAction = null); Task GetAccount(long id, Action? successAction = null, Action? notFoundAction = null); Task PutAccountProfileInfo(AccountProfileInfoRequest data, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null); Task PatchAccountUsername(AccountUsernameRequest data, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null); Task PatchAccountEmail(AccountEmailRequest data, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null); Task PatchAccountPassword(AccountPasswordRequest data, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null); - Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query, Action>? successAction = null, Action? notFoundAction = null); - Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters query, Action>? successAction = null, Action? notFoundAction = null); - Task GetAccountRatedPersons(long id, PersonRatedQueryParameters query, Action>? successAction = null, Action? notFoundAction = null); + Task GetAccountRatedMovies(long id, MovieRatedQueryParameters? query = null, Action>? successAction = null, Action? notFoundAction = null); + Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters? query = null, Action>? successAction = null, Action? notFoundAction = null); + Task GetAccountRatedPersons(long id, PersonRatedQueryParameters? query = null, Action>? successAction = null, Action? notFoundAction = null); + Task GetAccountFollows(long id, AccountQueryParameters? query = null, Action>? successAction = null, Action? notFoundAction = null); + Task GetAccountFollowers(long id, AccountQueryParameters? query = null, Action>? successAction = null, Action? notFoundAction = null); + Task PostAccountFollow(long userId, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null); + Task DeleteAccountFollow(long userId, Action? successAction = null, Action? unauthorizedAction = null); } \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Accounts.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Accounts.cs index eae345a..9793d7b 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Accounts.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Accounts.cs @@ -22,4 +22,8 @@ public class Accounts public string GetAccountRatedMovies { get; set; } public string GetAccountRatedSeries { get; set; } public string GetAccountRatedPersons { get; set; } + public string GetAccountFollows { get; set; } + public string GetAccountFollowers { get; set; } + public string PostAccountFollow { get; set; } + public string DeleteAccountFollow { get; set; } } \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/App.razor b/WatchIt.Website/WatchIt.Website/App.razor index f460abd..7dc152c 100644 --- a/WatchIt.Website/WatchIt.Website/App.razor +++ b/WatchIt.Website/WatchIt.Website/App.razor @@ -9,7 +9,7 @@ - + diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/SearchPage/Subcomponents/UserSearchResultItemComponent.razor b/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/UserListItemComponent.razor similarity index 80% rename from WatchIt.Website/WatchIt.Website/Components/Pages/SearchPage/Subcomponents/UserSearchResultItemComponent.razor rename to WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/UserListItemComponent.razor index dc936c9..771575a 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/SearchPage/Subcomponents/UserSearchResultItemComponent.razor +++ b/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/UserListItemComponent.razor @@ -1,7 +1,7 @@
+ Size="@(PictureSize)"/>

@(Item.Username)

\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/SearchPage/Subcomponents/UserSearchResultItemComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/UserListItemComponent.razor.cs similarity index 51% rename from WatchIt.Website/WatchIt.Website/Components/Pages/SearchPage/Subcomponents/UserSearchResultItemComponent.razor.cs rename to WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/UserListItemComponent.razor.cs index b81a075..a96df02 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/SearchPage/Subcomponents/UserSearchResultItemComponent.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/UserListItemComponent.razor.cs @@ -1,13 +1,14 @@ using Microsoft.AspNetCore.Components; using WatchIt.Common.Model.Accounts; -namespace WatchIt.Website.Components.Pages.SearchPage.Subcomponents; +namespace WatchIt.Website.Components.Common.Subcomponents; -public partial class UserSearchResultItemComponent : ComponentBase +public partial class UserListItemComponent : ComponentBase { #region PROPERTIES [Parameter] public required AccountResponse Item { get; set; } + [Parameter] public int PictureSize { get; set; } = 90; #endregion } \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/SearchPage/Panels/UsersSearchResultPanelComponent.razor b/WatchIt.Website/WatchIt.Website/Components/Pages/SearchPage/Panels/UsersSearchResultPanelComponent.razor index cb5dd8e..af69ba3 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/SearchPage/Panels/UsersSearchResultPanelComponent.razor +++ b/WatchIt.Website/WatchIt.Website/Components/Pages/SearchPage/Panels/UsersSearchResultPanelComponent.razor @@ -1,5 +1,4 @@ @using Blazorise.Extensions -@using WatchIt.Website.Components.Pages.SearchPage.Subcomponents @@ -29,7 +28,7 @@ @{ int iCopy = i; } - + } diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/FollowListPanelComponent.razor b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/FollowListPanelComponent.razor new file mode 100644 index 0000000..db95930 --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/FollowListPanelComponent.razor @@ -0,0 +1,29 @@ +
+
+

@(Title)

+
+ @if (!_loaded) + { +
+ +
+ } + else if (!_items.Any()) + { +
+
+ No items +
+
+ } + else + { + foreach (AccountResponse item in _items) + { +
+ +
+ } + } +
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/FollowListPanelComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/FollowListPanelComponent.razor.cs new file mode 100644 index 0000000..8cf1cc8 --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/FollowListPanelComponent.razor.cs @@ -0,0 +1,41 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Common.Model.Accounts; + +namespace WatchIt.Website.Components.Pages.UserPage.Panels; + +public partial class FollowListPanelComponent : ComponentBase +{ + #region PARAMETERS + + [Parameter] public required string Title { get; set; } + [Parameter] public required Func>, Task> DownloadItemsMethod { get; set; } + + #endregion + + + + #region FIELDS + + private bool _loaded; + + private List _items = []; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await DownloadItemsMethod.Invoke(data => _items.AddRange(data)); + + _loaded = true; + StateHasChanged(); + } + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/UserPageHeaderPanelComponent.razor b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/UserPageHeaderPanelComponent.razor index 28059b2..35214d5 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/UserPageHeaderPanelComponent.razor +++ b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/UserPageHeaderPanelComponent.razor @@ -1,29 +1,49 @@
- +
-

@(AccountProfileInfoData.Username)

+

@(Data.Username)

- @if (!string.IsNullOrWhiteSpace(AccountProfileInfoData.Description)) + @if (!string.IsNullOrWhiteSpace(Data.Description)) { - @(AccountProfileInfoData.Description) + @(Data.Description) }
diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/UserPageHeaderPanelComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/UserPageHeaderPanelComponent.razor.cs index a7d9ecd..f928b3f 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/UserPageHeaderPanelComponent.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Panels/UserPageHeaderPanelComponent.razor.cs @@ -9,7 +9,6 @@ public partial class UserPageHeaderPanelComponent : ComponentBase { #region SERVICES - [Inject] private IAuthenticationService AuthenticationService { get; set; } = default!; [Inject] private IAccountsClientService AccountsClientService { get; set; } = default!; #endregion @@ -18,38 +17,45 @@ public partial class UserPageHeaderPanelComponent : ComponentBase #region PARAMETERS - [Parameter] public required AccountResponse AccountProfileInfoData { get; set; } + [Parameter] public required AccountResponse Data { get; set; } + [Parameter] public required List Followers { get; set; } + [Parameter] public AccountResponse? LoggedUserData { get; set; } + [Parameter] public Action? FollowingChanged { get; set; } #endregion #region FIELDS + + private bool _followLoading; - private AccountProfilePictureResponse? _accountProfilePicture; - #endregion - - - + + + #region PRIVATE METHODS - protected override async Task OnAfterRenderAsync(bool firstRender) + private async Task Follow() { - if (firstRender) + _followLoading = true; + if (Followers.Any(x => x.Id == LoggedUserData!.Id)) { - List endTasks = new List(); - - // STEP 0 - endTasks.AddRange( - [ - AccountsClientService.GetAccountProfilePicture(AccountProfileInfoData.Id, data => _accountProfilePicture = data), - ]); - - // END - await Task.WhenAll(endTasks); - - StateHasChanged(); + await AccountsClientService.DeleteAccountFollow(Data.Id, () => + { + Followers.RemoveAll(x => x.Id == LoggedUserData!.Id); + FollowingChanged?.Invoke(false); + _followLoading = false; + }); + } + else + { + await AccountsClientService.PostAccountFollow(Data.Id, () => + { + Followers.Add(LoggedUserData); + FollowingChanged?.Invoke(true); + _followLoading = false; + }); } } diff --git a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor b/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor index 722e501..94f5a6e 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor +++ b/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor @@ -48,10 +48,12 @@ {
- +
-
+
Movies TV Series People + Follows + Followers @@ -160,22 +164,34 @@ PictureDownloadingTask="@((id, action) => PersonsClientService.GetPersonPhoto(id, action))" ItemDownloadingTask="@((query, action) => AccountsClientService.GetAccountRatedPersons(_accountData.Id, query, action))" SortingOptions="@(new Dictionary - { - { "user_rating.average", "Average user rating" }, - { "user_rating.count", "Number of user ratings" }, - { "user_rating_last_date", "User rating date" }, - { "rating.average", "Average rating" }, - { "rating.count", "Number of ratings" }, - { "name", "Name" }, - { "birth_date", "Birth date" }, - { "death_date", "Death date" }, - })" + { + { "user_rating.average", "Average user rating" }, + { "user_rating.count", "Number of user ratings" }, + { "user_rating_last_date", "User rating date" }, + { "rating.average", "Average rating" }, + { "rating.count", "Number of ratings" }, + { "name", "Name" }, + { "birth_date", "Birth date" }, + { "death_date", "Death date" }, + })" PosterPlaceholder="/assets/person_poster.png" GetGlobalRatingMethod="@((id, action) => PersonsClientService.GetPersonGlobalRating(id, action))">
+ +
+ +
+
+ +
+ +
+
diff --git a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs index 41cec0a..de0c490 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs @@ -38,7 +38,11 @@ public partial class UserPage : ComponentBase private bool _loaded; private bool _redirection; private bool _owner; + private User? _user; + + private AccountResponse? _loggedUserData; private AccountResponse? _accountData; + private List _followers; #endregion @@ -66,8 +70,13 @@ public partial class UserPage : ComponentBase await Task.WhenAll(step1Tasks); endTasks.AddRange( [ - AccountsClientService.GetAccountProfileBackground(_accountData.Id, data => Layout.BackgroundPhoto = data) + AccountsClientService.GetAccountProfileBackground(_accountData.Id, data => Layout.BackgroundPhoto = data), + AccountsClientService.GetAccountFollowers(_accountData.Id, successAction: data => _followers = data.ToList()) ]); + if (_user is not null) + { + endTasks.Add(AccountsClientService.GetAccount(_user.Id, data => _loggedUserData = data)); + } // END await Task.WhenAll(endTasks); @@ -79,20 +88,20 @@ public partial class UserPage : ComponentBase private async Task GetUserData() { - User? user = await AuthenticationService.GetUserAsync(); + _user = await AuthenticationService.GetUserAsync(); if (!Id.HasValue) { - if (user is null) + if (_user is null) { NavigationManager.NavigateTo($"/auth?redirect_to={WebUtility.UrlEncode("/user")}"); _redirection = true; return; } - Id = user.Id; + Id = _user.Id; } await AccountsClientService.GetAccount(Id.Value, data => _accountData = data); - _owner = Id.Value == user?.Id; + _owner = Id.Value == _user?.Id; } diff --git a/WatchIt.Website/WatchIt.Website/appsettings.json b/WatchIt.Website/WatchIt.Website/appsettings.json index 72afefa..ba6fad3 100644 --- a/WatchIt.Website/WatchIt.Website/appsettings.json +++ b/WatchIt.Website/WatchIt.Website/appsettings.json @@ -35,7 +35,11 @@ "PatchAccountPassword": "/password", "GetAccountRatedMovies": "/{0}/movies", "GetAccountRatedSeries": "/{0}/series", - "GetAccountRatedPersons": "/{0}/persons" + "GetAccountRatedPersons": "/{0}/persons", + "GetAccountFollows": "/{0}/follows", + "GetAccountFollowers": "/{0}/followers", + "PostAccountFollow": "/follows/{0}", + "DeleteAccountFollow": "/follows/{0}" }, "Genders": { "Base": "/genders", diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/css/general.css b/WatchIt.Website/WatchIt.Website/wwwroot/css/general.css index 319ee59..5cc54b1 100644 --- a/WatchIt.Website/WatchIt.Website/wwwroot/css/general.css +++ b/WatchIt.Website/WatchIt.Website/wwwroot/css/general.css @@ -66,6 +66,11 @@ body, html { gap: 1rem; } +.metadata-pill-hoverable:hover { + background-color: gray; + color: black; +} +