diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..9ce79f7 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +.previous-attempts diff --git a/src/docker-compose.yaml b/src/docker-compose.yaml new file mode 100644 index 0000000..2a089c9 --- /dev/null +++ b/src/docker-compose.yaml @@ -0,0 +1,23 @@ +services: + zitadel: + restart: 'always' + networks: + - 'zitadel' + image: 'ghcr.io/zitadel/zitadel:latest' + command: 'start-from-init --masterkey "VTma693bDYV6ccpdaHRdQejl46eSQTa0" --tlsMode disabled' + environment: + - 'ZITADEL_DATABASE_POSTGRES_HOST=10.1.1.1' + - 'ZITADEL_DATABASE_POSTGRES_PORT=5432' + - 'ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel' + - 'ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel' + - 'ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel' + - 'ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable' + - 'ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=postgres' + - 'ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD=hackme' + - 'ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable' + - 'ZITADEL_EXTERNALSECURE=false' + ports: + - '8080:8080' + +networks: + zitadel: diff --git a/src/tvnoms-server/TvNoms.ApiService/Endpoints/ShowEndpoints.cs b/src/tvnoms-server/TvNoms.ApiService/Endpoints/ShowEndpoints.cs index 5bbb6a8..29587fb 100644 --- a/src/tvnoms-server/TvNoms.ApiService/Endpoints/ShowEndpoints.cs +++ b/src/tvnoms-server/TvNoms.ApiService/Endpoints/ShowEndpoints.cs @@ -1,10 +1,13 @@ +using AutoMapper; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc; +using TvNoms.Core.DTO; using TvNoms.Core.MediaLookup; +using TvNoms.Core.Models; +using TvNoms.Core.Utilities; namespace TvNoms.Server.ApiService.Endpoints; -[EnableCors("WebAppCors")] public class ShowEndpoints : Shared.Endpoints { public ShowEndpoints(IEndpointRouteBuilder endpointRouteBuilder) : base(endpointRouteBuilder) { @@ -12,11 +15,21 @@ public class ShowEndpoints : Shared.Endpoints { public override void Configure() { var endpoints = MapGroup("/shows"); - endpoints.MapGet("/{type}/trending", GetTrending).RequireAuthorization(); } - public async Task GetTrending([FromServices] IShowLookupService showLookupService) { - return Results.Ok(await showLookupService.GetTrendingShows()); + public async Task GetTrending( + [FromServices] IMapper mapper, + [FromServices] IModelBuilder modelBuilder, + [FromServices] IShowLookupService showLookupService) { + var trendingResults = await showLookupService.GetTrendingShows(); + var dto = mapper.Map>(trendingResults.Items); + + var response = new Pageable( + trendingResults.Page, + trendingResults.TotalPages, + trendingResults.TotalResults, + dto); + return await modelBuilder.BuildAsync(response); } } diff --git a/src/tvnoms-server/TvNoms.ApiService/Endpoints/UserEndpoints.cs b/src/tvnoms-server/TvNoms.ApiService/Endpoints/UserEndpoints.cs index 35a8ba6..0776ced 100644 --- a/src/tvnoms-server/TvNoms.ApiService/Endpoints/UserEndpoints.cs +++ b/src/tvnoms-server/TvNoms.ApiService/Endpoints/UserEndpoints.cs @@ -14,7 +14,6 @@ using TvNoms.Server.Services; namespace TvNoms.Server.ApiService.Endpoints; -[EnableCors("WebAppCors")] public class UserEndpoints : Shared.Endpoints { public UserEndpoints(IEndpointRouteBuilder endpointRouteBuilder) : base(endpointRouteBuilder) { @@ -61,12 +60,10 @@ public class UserEndpoints : Shared.Endpoints { return Results.Ok(); } - [EnableCors("WebAppCors")] public async Task SignInAsync([FromServices] IUserService userService, [FromBody] SignInForm form) { return Results.Ok(await userService.SignInAsync(form)); } - [EnableCors("WebAppCors")] public async Task SignInWithAsync( [FromServices] IUserService userService, [FromServices] SignInManager signInManager, @@ -103,7 +100,6 @@ public class UserEndpoints : Shared.Endpoints { return Results.Ok(await userService.SignInWithAsync(form)); } - [EnableCors("WebAppCors")] public IResult SignInWithRedirectAsync( [FromServices] SignInManager signInManager, [FromServices] IConfiguration configuration, @@ -170,7 +166,8 @@ public class UserEndpoints : Shared.Endpoints { public async Task GetUsersAsync([FromServices] IUserService userService, [AsParameters] UserCriteria criteria, [FromQuery] long offset = 0, [FromQuery] int limit = 25) { - return Results.Ok(await userService.GetUsersAsync(criteria, offset, limit)); + var user = await userService.GetUsersAsync(criteria, offset, limit); + return Results.Ok(user); } public async Task GetCurrentUserAsync([FromServices] IUserService userService) { diff --git a/src/tvnoms-server/TvNoms.ApiService/Program.cs b/src/tvnoms-server/TvNoms.ApiService/Program.cs index 27e9e3b..c3d117b 100644 --- a/src/tvnoms-server/TvNoms.ApiService/Program.cs +++ b/src/tvnoms-server/TvNoms.ApiService/Program.cs @@ -118,6 +118,7 @@ builder.Services.AddIdentity(options => { builder.Services.AddClientContext(); builder.Services.AddHttpContextAccessor(); +builder.Services.AddWebAppCors(builder.Configuration); builder.Services.AddAuthentication(options => { options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme; @@ -130,8 +131,9 @@ builder.Services.AddAuthentication(options => { options.SignInScheme = IdentityConstants.ExternalScheme; builder.Configuration.GetRequiredSection("GoogleAuthOptions").Bind(options); }); -builder.Services.AddModelBuilder(); builder.Services.AddAuthorization(); + +builder.Services.AddModelBuilder(); builder.Services.AddMailgunEmailSender(options => { builder.Configuration.GetRequiredSection("MailgunEmailOptions").Bind(options); }); @@ -143,7 +145,6 @@ builder.Services.AddLocalFileStorage(options => { options.WebRootPath = "/uploads"; }); builder.Services.AddDocumentations(); -builder.Services.AddWebAppCors(builder.Configuration); builder.Services.AddDistributedMemoryCache(); builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromSeconds(10); @@ -165,7 +166,10 @@ var app = builder.Build(); // Configure the HTTP request pipeline. app.UseExceptionHandler(); -app.UseCors("WebAppPolicy"); +app.UseCors("WebAppCors"); + +app.UseAuthentication(); +app.UseAuthorization(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); diff --git a/src/tvnoms-server/TvNoms.ApiService/Shared/Endpoints.cs b/src/tvnoms-server/TvNoms.ApiService/Shared/Endpoints.cs index dee1c4d..f6b928c 100644 --- a/src/tvnoms-server/TvNoms.ApiService/Shared/Endpoints.cs +++ b/src/tvnoms-server/TvNoms.ApiService/Shared/Endpoints.cs @@ -14,6 +14,7 @@ public abstract class Endpoints { .MapGroup(prefix) //.WithGroupName(groupName) .WithTags(groupName) + .RequireCors() .WithOpenApi(); } diff --git a/src/tvnoms-server/TvNoms.Core/DTO/ShowDto.cs b/src/tvnoms-server/TvNoms.Core/DTO/ShowDto.cs new file mode 100644 index 0000000..650d97b --- /dev/null +++ b/src/tvnoms-server/TvNoms.Core/DTO/ShowDto.cs @@ -0,0 +1,44 @@ +using TvNoms.Core.MediaLookup; + +namespace TvNoms.Core.DTO; + +using AbstractProfile = AutoMapper.Profile; + +public class ShowDto { + public string Title { get; set; } + public long TheMovieDbId { get; set; } + + public float Popularity { get; set; } + public float AverageVote { get; set; } + public long VoteCount { get; set; } + public string BackdropImage { get; set; } + public string PosterImage { get; set; } + public DateTime FirstAired { get; set; } + public bool IsAdult { get; set; } + + public long[] GenreIds { get; set; } +} + +public class ShowDtoProfile : AbstractProfile { + public ShowDtoProfile() { + CreateMap() + .ForMember(src => src.PosterImage, + dest => dest.MapFrom(e => $"https://image.tmdb.org/t/p/w1280{e.PosterImage}")) + .ForMember(src => src.BackdropImage, + dest => dest.MapFrom(e => $"https://image.tmdb.org/t/p/w1280{e.BackdropImage}")); + } +} + +public class ShowPageModel { + public long Offset { get; set; } + + public int Limit { get; set; } + + public long Length { get; set; } + + public long? Previous { get; set; } + + public long? Next { get; set; } + + public IList Items { get; set; } = new List(); +} diff --git a/src/tvnoms-server/TvNoms.Core/Extensions/DeserializeExtensions.cs b/src/tvnoms-server/TvNoms.Core/Extensions/DeserializeExtensions.cs index c82d1cd..9043a6a 100644 --- a/src/tvnoms-server/TvNoms.Core/Extensions/DeserializeExtensions.cs +++ b/src/tvnoms-server/TvNoms.Core/Extensions/DeserializeExtensions.cs @@ -4,9 +4,9 @@ using System.Text.Json.Serialization; namespace TvNoms.Core.Extensions; public static class DeserializeExtensions { - private static readonly JsonSerializerOptions _config = new JsonSerializerOptions { - NumberHandling = JsonNumberHandling.AllowReadingFromString | - JsonNumberHandling.WriteAsString + private static readonly JsonSerializerOptions _config = new() { + NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; public static async Task DeserializeHttpContent(this HttpContent content, diff --git a/src/tvnoms-server/TvNoms.Core/MediaLookup/IShowLookupService.cs b/src/tvnoms-server/TvNoms.Core/MediaLookup/IShowLookupService.cs index caddd20..d010742 100644 --- a/src/tvnoms-server/TvNoms.Core/MediaLookup/IShowLookupService.cs +++ b/src/tvnoms-server/TvNoms.Core/MediaLookup/IShowLookupService.cs @@ -1,12 +1,13 @@ using System.Text.Json.Serialization; +using AbstractProfile = AutoMapper.Profile; namespace TvNoms.Core.MediaLookup; -public class TheMovieDbResult { +public class TheMovieDbResult : AbstractProfile { [JsonPropertyName("page")] public int Page { get; set; } [JsonPropertyName("total_pages")] public int TotalPages { get; set; } [JsonPropertyName("total_results")] public int TotalResults { get; set; } - [JsonPropertyName("results")] public List Results { get; set; } + [JsonPropertyName("results")] public List Items { get; set; } } public class RemoteShowModel { diff --git a/src/tvnoms-server/TvNoms.Core/Models/Medias/DeleteMediaForm.cs b/src/tvnoms-server/TvNoms.Core/Models/Media/DeleteMediaForm.cs similarity index 100% rename from src/tvnoms-server/TvNoms.Core/Models/Medias/DeleteMediaForm.cs rename to src/tvnoms-server/TvNoms.Core/Models/Media/DeleteMediaForm.cs diff --git a/src/tvnoms-server/TvNoms.Core/Models/Medias/MediaModel.cs b/src/tvnoms-server/TvNoms.Core/Models/Media/MediaModel.cs similarity index 100% rename from src/tvnoms-server/TvNoms.Core/Models/Medias/MediaModel.cs rename to src/tvnoms-server/TvNoms.Core/Models/Media/MediaModel.cs diff --git a/src/tvnoms-server/TvNoms.Core/Models/Medias/UploadMediaChunkForm.cs b/src/tvnoms-server/TvNoms.Core/Models/Media/UploadMediaChunkForm.cs similarity index 100% rename from src/tvnoms-server/TvNoms.Core/Models/Medias/UploadMediaChunkForm.cs rename to src/tvnoms-server/TvNoms.Core/Models/Media/UploadMediaChunkForm.cs diff --git a/src/tvnoms-server/TvNoms.Core/Models/Medias/UploadMediaContentForm.cs b/src/tvnoms-server/TvNoms.Core/Models/Media/UploadMediaContentForm.cs similarity index 100% rename from src/tvnoms-server/TvNoms.Core/Models/Medias/UploadMediaContentForm.cs rename to src/tvnoms-server/TvNoms.Core/Models/Media/UploadMediaContentForm.cs diff --git a/src/tvnoms-server/TvNoms.Core/Models/ModelBuilder.cs b/src/tvnoms-server/TvNoms.Core/Models/ModelBuilder.cs index 5dad34b..ed1caf8 100644 --- a/src/tvnoms-server/TvNoms.Core/Models/ModelBuilder.cs +++ b/src/tvnoms-server/TvNoms.Core/Models/ModelBuilder.cs @@ -1,5 +1,6 @@ using AutoMapper; using Humanizer; +using TvNoms.Core.DTO; using TvNoms.Core.Entities; using TvNoms.Core.Extensions.Identity; using TvNoms.Core.FileStorage; @@ -16,6 +17,9 @@ public interface IModelBuilder { Task BuildAsync(User user, CancellationToken cancellationToken = default); Task BuildAsync(IPageable users, CancellationToken cancellationToken = default); + + + Task BuildAsync(IPageable shows, CancellationToken cancellationToken = default); } public class ModelBuilder : IModelBuilder { @@ -85,4 +89,18 @@ public class ModelBuilder : IModelBuilder { }; return listModel; } + + public async Task BuildAsync(IPageable shows, CancellationToken cancellationToken = default) { + ArgumentNullException.ThrowIfNull(shows); + + var listModel = new ShowPageModel() { + Items = shows.Items, + Offset = shows.Offset, + Limit = shows.Limit, + Length = shows.Length, + Previous = shows.Previous, + Next = shows.Next + }; + return listModel; + } } diff --git a/src/tvnoms-server/TvNoms.Core/Utilities/IPageable.cs b/src/tvnoms-server/TvNoms.Core/Utilities/IPageable.cs index 793f71b..e3b9aee 100644 --- a/src/tvnoms-server/TvNoms.Core/Utilities/IPageable.cs +++ b/src/tvnoms-server/TvNoms.Core/Utilities/IPageable.cs @@ -6,4 +6,5 @@ public interface IPageable : IEnumerable { long Length { get; } long? Previous { get; } long? Next { get; } + IList? Items { get; } } diff --git a/src/tvnoms-server/TvNoms.Core/Utilities/Pageable.cs b/src/tvnoms-server/TvNoms.Core/Utilities/Pageable.cs index 23ec66a..5a06986 100644 --- a/src/tvnoms-server/TvNoms.Core/Utilities/Pageable.cs +++ b/src/tvnoms-server/TvNoms.Core/Utilities/Pageable.cs @@ -1,24 +1,29 @@ using System.Collections; +using System.Text.Json.Serialization; namespace TvNoms.Core.Utilities; public class Pageable : IPageable { - public Pageable(long offset, int limit, long total, IEnumerable items) { + public Pageable() { + } + + public Pageable(long offset, int limit, long total, List items) { Offset = offset; Limit = limit; Length = total; Items = items; } + [JsonPropertyName("Offset")] public long Offset { get; } public int Limit { get; } public long Length { get; } - public IEnumerable Items { get; } + public IList? Items { get; } = new List(); public long? Previous => Offset - Limit >= 0 ? Offset - Limit : null; public long? Next => Offset + Limit < Length ? Offset + Limit : null; public IEnumerator GetEnumerator() { - return Items.GetEnumerator(); + return Items?.GetEnumerator() ?? new List.Enumerator(); } IEnumerator IEnumerable.GetEnumerator() { diff --git a/src/tvnoms-server/TvNoms.Data/Migrations/20240327214813_Initial.Designer.cs b/src/tvnoms-server/TvNoms.Data/Migrations/20240327214813_Initial.Designer.cs new file mode 100644 index 0000000..2d5089e --- /dev/null +++ b/src/tvnoms-server/TvNoms.Data/Migrations/20240327214813_Initial.Designer.cs @@ -0,0 +1,884 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using TvNoms.Server.Data; + +#nullable disable + +namespace TvNoms.Server.Data.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20240327214813_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("tvnoms") + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("GenreMovie", b => + { + b.Property("GenresId") + .HasColumnType("uuid") + .HasColumnName("genres_id"); + + b.Property("MovieId") + .HasColumnType("uuid") + .HasColumnName("movie_id"); + + b.HasKey("GenresId", "MovieId") + .HasName("pk___movie_genres"); + + b.HasIndex("MovieId") + .HasDatabaseName("ix___movie_genres_movie_id"); + + b.ToTable("__movie_genres", "tvnoms"); + }); + + modelBuilder.Entity("GenreShow", b => + { + b.Property("GenresId") + .HasColumnType("uuid") + .HasColumnName("genres_id"); + + b.Property("ShowId") + .HasColumnType("uuid") + .HasColumnName("show_id"); + + b.HasKey("GenresId", "ShowId") + .HasName("pk___show_genres"); + + b.HasIndex("ShowId") + .HasDatabaseName("ix___show_genres_show_id"); + + b.ToTable("__show_genres", "tvnoms"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("name"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_name"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("user_user_role", "auth"); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text") + .HasColumnName("claim_type"); + + b.Property("ClaimValue") + .HasColumnType("text") + .HasColumnName("claim_value"); + + b.Property("RoleId") + .HasColumnType("uuid") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_role_claim"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_role_claim_role_id"); + + b.ToTable("role_claim", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("text") + .HasColumnName("id"); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasColumnName("access_failed_count"); + + b.Property("ConcurrencyStamp") + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Email") + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasColumnName("email_confirmed"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasColumnName("lockout_enabled"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("lockout_end"); + + b.Property("NormalizedEmail") + .HasColumnType("text") + .HasColumnName("normalized_email"); + + b.Property("NormalizedUserName") + .HasColumnType("text") + .HasColumnName("normalized_user_name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PhoneNumber") + .HasColumnType("text") + .HasColumnName("phone_number"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasColumnName("phone_number_confirmed"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasColumnName("security_stamp"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasColumnName("two_factor_enabled"); + + b.Property("UserName") + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("pk_identity_user_base"); + + b.ToTable("identity_user_base", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasColumnName("access_failed_count"); + + b.Property("ConcurrencyStamp") + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Email") + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasColumnName("email_confirmed"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasColumnName("lockout_enabled"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("lockout_end"); + + b.Property("NormalizedEmail") + .HasColumnType("text") + .HasColumnName("normalized_email"); + + b.Property("NormalizedUserName") + .HasColumnType("text") + .HasColumnName("normalized_user_name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PhoneNumber") + .HasColumnType("text") + .HasColumnName("phone_number"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasColumnName("phone_number_confirmed"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasColumnName("security_stamp"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasColumnName("two_factor_enabled"); + + b.Property("UserName") + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("pk_identity_user"); + + b.ToTable("identity_user", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text") + .HasColumnName("claim_type"); + + b.Property("ClaimValue") + .HasColumnType("text") + .HasColumnName("claim_value"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_user_claim"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_user_claim_user_id"); + + b.ToTable("user_claim", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text") + .HasColumnName("login_provider"); + + b.Property("ProviderKey") + .HasColumnType("text") + .HasColumnName("provider_key"); + + b.Property("ProviderDisplayName") + .HasColumnType("text") + .HasColumnName("provider_display_name"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("LoginProvider", "ProviderKey") + .HasName("pk_user_login"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_user_login_user_id"); + + b.ToTable("user_login", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("RoleId") + .HasColumnType("uuid") + .HasColumnName("role_id"); + + b.HasKey("UserId", "RoleId") + .HasName("pk_user_identity_role"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_user_identity_role_role_id"); + + b.ToTable("user_identity_role", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("LoginProvider") + .HasColumnType("text") + .HasColumnName("login_provider"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Value") + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("UserId", "LoginProvider", "Name") + .HasName("pk_user_token"); + + b.ToTable("user_token", "auth"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Active") + .HasColumnType("boolean") + .HasColumnName("active"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("connection_id"); + + b.Property("ConnectionTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("connection_time"); + + b.Property("DateCreated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateUpdated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_updated"); + + b.Property("DeviceId") + .HasColumnType("text") + .HasColumnName("device_id"); + + b.Property("IpAddress") + .HasColumnType("text") + .HasColumnName("ip_address"); + + b.Property("UserAgent") + .HasColumnType("text") + .HasColumnName("user_agent"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_clients"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_clients_user_id"); + + b.ToTable("clients", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateCreated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateUpdated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_updated"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_genres"); + + b.HasIndex("Name") + .IsUnique() + .HasDatabaseName("ix_genres_name"); + + b.ToTable("genres", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Media", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("text") + .HasColumnName("content_type"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DateCreated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateUpdated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_updated"); + + b.Property("Height") + .HasColumnType("integer") + .HasColumnName("height"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Path") + .IsRequired() + .HasColumnType("text") + .HasColumnName("path"); + + b.Property("Size") + .HasColumnType("bigint") + .HasColumnName("size"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.Property("Width") + .HasColumnType("integer") + .HasColumnName("width"); + + b.HasKey("Id") + .HasName("pk_media"); + + b.ToTable("media", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Movie", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateCreated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateUpdated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_updated"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text") + .HasColumnName("title"); + + b.HasKey("Id") + .HasName("pk_movies"); + + b.ToTable("movies", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Show", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateCreated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateUpdated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_updated"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text") + .HasColumnName("title"); + + b.HasKey("Id") + .HasName("pk_shows"); + + b.ToTable("shows", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasColumnName("access_failed_count"); + + b.Property("Active") + .HasColumnType("boolean") + .HasColumnName("active"); + + b.Property("AvatarId") + .HasColumnType("uuid") + .HasColumnName("avatar_id"); + + b.Property("Bio") + .HasColumnType("text") + .HasColumnName("bio"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("email"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasColumnName("email_confirmed"); + + b.Property("EmailRequired") + .HasColumnType("boolean") + .HasColumnName("email_required"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("first_name"); + + b.Property("LastActiveAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_active_at"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("last_name"); + + b.Property("Location") + .HasColumnType("text") + .HasColumnName("location"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasColumnName("lockout_enabled"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("lockout_end"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_email"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_user_name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PhoneNumber") + .HasColumnType("text") + .HasColumnName("phone_number"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasColumnName("phone_number_confirmed"); + + b.Property("PhoneNumberRequired") + .HasColumnType("boolean") + .HasColumnName("phone_number_required"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasColumnName("security_stamp"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasColumnName("two_factor_enabled"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("pk_user"); + + b.HasIndex("AvatarId") + .HasDatabaseName("ix_user_avatar_id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("user", "auth"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.UserSession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccessTokenExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("access_token_expires_at"); + + b.Property("AccessTokenHash") + .IsRequired() + .HasColumnType("text") + .HasColumnName("access_token_hash"); + + b.Property("RefreshTokenExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("refresh_token_expires_at"); + + b.Property("RefreshTokenHash") + .IsRequired() + .HasColumnType("text") + .HasColumnName("refresh_token_hash"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_user_sessions"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_user_sessions_user_id"); + + b.ToTable("user_sessions", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Role", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityRole"); + + b.ToTable("roles", "auth"); + }); + + modelBuilder.Entity("GenreMovie", b => + { + b.HasOne("TvNoms.Core.Entities.Genre", null) + .WithMany() + .HasForeignKey("GenresId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk___movie_genres_genres_genres_id"); + + b.HasOne("TvNoms.Core.Entities.Movie", null) + .WithMany() + .HasForeignKey("MovieId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk___movie_genres_movies_movie_id"); + }); + + modelBuilder.Entity("GenreShow", b => + { + b.HasOne("TvNoms.Core.Entities.Genre", null) + .WithMany() + .HasForeignKey("GenresId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk___show_genres_genres_genres_id"); + + b.HasOne("TvNoms.Core.Entities.Show", null) + .WithMany() + .HasForeignKey("ShowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk___show_genres_shows_show_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_role_claim_user_user_role_role_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("TvNoms.Core.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_claim_user_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("TvNoms.Core.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_login_user_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_identity_role_user_user_role_role_id"); + + b.HasOne("TvNoms.Core.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_identity_role_user_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("TvNoms.Core.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_token_user_user_id"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Client", b => + { + b.HasOne("TvNoms.Core.Entities.User", "User") + .WithMany("Clients") + .HasForeignKey("UserId") + .HasConstraintName("fk_clients_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.User", b => + { + b.HasOne("TvNoms.Core.Entities.Media", "Avatar") + .WithMany() + .HasForeignKey("AvatarId") + .HasConstraintName("fk_user_media_avatar_id"); + + b.Navigation("Avatar"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.UserSession", b => + { + b.HasOne("TvNoms.Core.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_sessions_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Role", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithOne() + .HasForeignKey("TvNoms.Core.Entities.Role", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_roles_user_user_role_id"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.User", b => + { + b.Navigation("Clients"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/tvnoms-server/TvNoms.Data/Migrations/20240327214813_Initial.cs b/src/tvnoms-server/TvNoms.Data/Migrations/20240327214813_Initial.cs new file mode 100644 index 0000000..f70808d --- /dev/null +++ b/src/tvnoms-server/TvNoms.Data/Migrations/20240327214813_Initial.cs @@ -0,0 +1,597 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace TvNoms.Server.Data.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "tvnoms"); + + migrationBuilder.EnsureSchema( + name: "auth"); + + migrationBuilder.CreateTable( + name: "genres", + schema: "tvnoms", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + name = table.Column(type: "text", nullable: false), + description = table.Column(type: "text", nullable: false), + date_created = table.Column(type: "timestamp with time zone", nullable: false), + date_updated = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_genres", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "identity_user", + schema: "auth", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + user_name = table.Column(type: "text", nullable: true), + normalized_user_name = table.Column(type: "text", nullable: true), + email = table.Column(type: "text", nullable: true), + normalized_email = table.Column(type: "text", nullable: true), + email_confirmed = table.Column(type: "boolean", nullable: false), + password_hash = table.Column(type: "text", nullable: true), + security_stamp = table.Column(type: "text", nullable: true), + concurrency_stamp = table.Column(type: "text", nullable: true), + phone_number = table.Column(type: "text", nullable: true), + phone_number_confirmed = table.Column(type: "boolean", nullable: false), + two_factor_enabled = table.Column(type: "boolean", nullable: false), + lockout_end = table.Column(type: "timestamp with time zone", nullable: true), + lockout_enabled = table.Column(type: "boolean", nullable: false), + access_failed_count = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_identity_user", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "identity_user_base", + schema: "auth", + columns: table => new + { + id = table.Column(type: "text", nullable: false), + user_name = table.Column(type: "text", nullable: true), + normalized_user_name = table.Column(type: "text", nullable: true), + email = table.Column(type: "text", nullable: true), + normalized_email = table.Column(type: "text", nullable: true), + email_confirmed = table.Column(type: "boolean", nullable: false), + password_hash = table.Column(type: "text", nullable: true), + security_stamp = table.Column(type: "text", nullable: true), + concurrency_stamp = table.Column(type: "text", nullable: true), + phone_number = table.Column(type: "text", nullable: true), + phone_number_confirmed = table.Column(type: "boolean", nullable: false), + two_factor_enabled = table.Column(type: "boolean", nullable: false), + lockout_end = table.Column(type: "timestamp with time zone", nullable: true), + lockout_enabled = table.Column(type: "boolean", nullable: false), + access_failed_count = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_identity_user_base", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "media", + schema: "tvnoms", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + name = table.Column(type: "text", nullable: false), + size = table.Column(type: "bigint", nullable: false), + path = table.Column(type: "text", nullable: false), + content_type = table.Column(type: "text", nullable: false), + type = table.Column(type: "integer", nullable: false), + width = table.Column(type: "integer", nullable: true), + height = table.Column(type: "integer", nullable: true), + created_at = table.Column(type: "timestamp with time zone", nullable: false), + updated_at = table.Column(type: "timestamp with time zone", nullable: false), + date_created = table.Column(type: "timestamp with time zone", nullable: false), + date_updated = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_media", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "movies", + schema: "tvnoms", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + title = table.Column(type: "text", nullable: false), + date_created = table.Column(type: "timestamp with time zone", nullable: false), + date_updated = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_movies", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "shows", + schema: "tvnoms", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + title = table.Column(type: "text", nullable: false), + date_created = table.Column(type: "timestamp with time zone", nullable: false), + date_updated = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_shows", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "user_user_role", + schema: "auth", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + name = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + normalized_name = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + concurrency_stamp = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_user_user_role", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "user", + schema: "auth", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + first_name = table.Column(type: "text", nullable: false), + last_name = table.Column(type: "text", nullable: false), + avatar_id = table.Column(type: "uuid", nullable: true), + bio = table.Column(type: "text", nullable: true), + location = table.Column(type: "text", nullable: true), + active = table.Column(type: "boolean", nullable: false), + last_active_at = table.Column(type: "timestamp with time zone", nullable: false), + email_required = table.Column(type: "boolean", nullable: false), + phone_number_required = table.Column(type: "boolean", nullable: false), + user_name = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + normalized_user_name = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + email = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + normalized_email = table.Column(type: "character varying(256)", maxLength: 256, nullable: true), + email_confirmed = table.Column(type: "boolean", nullable: false), + password_hash = table.Column(type: "text", nullable: true), + security_stamp = table.Column(type: "text", nullable: true), + concurrency_stamp = table.Column(type: "text", nullable: true), + phone_number = table.Column(type: "text", nullable: true), + phone_number_confirmed = table.Column(type: "boolean", nullable: false), + two_factor_enabled = table.Column(type: "boolean", nullable: false), + lockout_end = table.Column(type: "timestamp with time zone", nullable: true), + lockout_enabled = table.Column(type: "boolean", nullable: false), + access_failed_count = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_user", x => x.id); + table.ForeignKey( + name: "fk_user_media_avatar_id", + column: x => x.avatar_id, + principalSchema: "tvnoms", + principalTable: "media", + principalColumn: "id"); + }); + + migrationBuilder.CreateTable( + name: "__movie_genres", + schema: "tvnoms", + columns: table => new + { + genres_id = table.Column(type: "uuid", nullable: false), + movie_id = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk___movie_genres", x => new { x.genres_id, x.movie_id }); + table.ForeignKey( + name: "fk___movie_genres_genres_genres_id", + column: x => x.genres_id, + principalSchema: "tvnoms", + principalTable: "genres", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk___movie_genres_movies_movie_id", + column: x => x.movie_id, + principalSchema: "tvnoms", + principalTable: "movies", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "__show_genres", + schema: "tvnoms", + columns: table => new + { + genres_id = table.Column(type: "uuid", nullable: false), + show_id = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk___show_genres", x => new { x.genres_id, x.show_id }); + table.ForeignKey( + name: "fk___show_genres_genres_genres_id", + column: x => x.genres_id, + principalSchema: "tvnoms", + principalTable: "genres", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk___show_genres_shows_show_id", + column: x => x.show_id, + principalSchema: "tvnoms", + principalTable: "shows", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "role_claim", + schema: "auth", + columns: table => new + { + id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + role_id = table.Column(type: "uuid", nullable: false), + claim_type = table.Column(type: "text", nullable: true), + claim_value = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("pk_role_claim", x => x.id); + table.ForeignKey( + name: "fk_role_claim_user_user_role_role_id", + column: x => x.role_id, + principalSchema: "auth", + principalTable: "user_user_role", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "roles", + schema: "auth", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_roles", x => x.id); + table.ForeignKey( + name: "fk_roles_user_user_role_id", + column: x => x.id, + principalSchema: "auth", + principalTable: "user_user_role", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "clients", + schema: "tvnoms", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + connection_id = table.Column(type: "text", nullable: false), + connection_time = table.Column(type: "timestamp with time zone", nullable: false), + ip_address = table.Column(type: "text", nullable: true), + device_id = table.Column(type: "text", nullable: true), + user_id = table.Column(type: "uuid", nullable: true), + user_agent = table.Column(type: "text", nullable: true), + active = table.Column(type: "boolean", nullable: false), + date_created = table.Column(type: "timestamp with time zone", nullable: false), + date_updated = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_clients", x => x.id); + table.ForeignKey( + name: "fk_clients_user_user_id", + column: x => x.user_id, + principalSchema: "auth", + principalTable: "user", + principalColumn: "id"); + }); + + migrationBuilder.CreateTable( + name: "user_claim", + schema: "auth", + columns: table => new + { + id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + user_id = table.Column(type: "uuid", nullable: false), + claim_type = table.Column(type: "text", nullable: true), + claim_value = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("pk_user_claim", x => x.id); + table.ForeignKey( + name: "fk_user_claim_user_user_id", + column: x => x.user_id, + principalSchema: "auth", + principalTable: "user", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "user_identity_role", + schema: "auth", + columns: table => new + { + user_id = table.Column(type: "uuid", nullable: false), + role_id = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_user_identity_role", x => new { x.user_id, x.role_id }); + table.ForeignKey( + name: "fk_user_identity_role_user_user_id", + column: x => x.user_id, + principalSchema: "auth", + principalTable: "user", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "fk_user_identity_role_user_user_role_role_id", + column: x => x.role_id, + principalSchema: "auth", + principalTable: "user_user_role", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "user_login", + schema: "auth", + columns: table => new + { + login_provider = table.Column(type: "text", nullable: false), + provider_key = table.Column(type: "text", nullable: false), + provider_display_name = table.Column(type: "text", nullable: true), + user_id = table.Column(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_user_login", x => new { x.login_provider, x.provider_key }); + table.ForeignKey( + name: "fk_user_login_user_user_id", + column: x => x.user_id, + principalSchema: "auth", + principalTable: "user", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "user_sessions", + schema: "tvnoms", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + user_id = table.Column(type: "uuid", nullable: false), + access_token_hash = table.Column(type: "text", nullable: false), + access_token_expires_at = table.Column(type: "timestamp with time zone", nullable: false), + refresh_token_hash = table.Column(type: "text", nullable: false), + refresh_token_expires_at = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("pk_user_sessions", x => x.id); + table.ForeignKey( + name: "fk_user_sessions_user_user_id", + column: x => x.user_id, + principalSchema: "auth", + principalTable: "user", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "user_token", + schema: "auth", + columns: table => new + { + user_id = table.Column(type: "uuid", nullable: false), + login_provider = table.Column(type: "text", nullable: false), + name = table.Column(type: "text", nullable: false), + value = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("pk_user_token", x => new { x.user_id, x.login_provider, x.name }); + table.ForeignKey( + name: "fk_user_token_user_user_id", + column: x => x.user_id, + principalSchema: "auth", + principalTable: "user", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "ix___movie_genres_movie_id", + schema: "tvnoms", + table: "__movie_genres", + column: "movie_id"); + + migrationBuilder.CreateIndex( + name: "ix___show_genres_show_id", + schema: "tvnoms", + table: "__show_genres", + column: "show_id"); + + migrationBuilder.CreateIndex( + name: "ix_clients_user_id", + schema: "tvnoms", + table: "clients", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_genres_name", + schema: "tvnoms", + table: "genres", + column: "name", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_role_claim_role_id", + schema: "auth", + table: "role_claim", + column: "role_id"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + schema: "auth", + table: "user", + column: "normalized_email"); + + migrationBuilder.CreateIndex( + name: "ix_user_avatar_id", + schema: "auth", + table: "user", + column: "avatar_id"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + schema: "auth", + table: "user", + column: "normalized_user_name", + unique: true); + + migrationBuilder.CreateIndex( + name: "ix_user_claim_user_id", + schema: "auth", + table: "user_claim", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_user_identity_role_role_id", + schema: "auth", + table: "user_identity_role", + column: "role_id"); + + migrationBuilder.CreateIndex( + name: "ix_user_login_user_id", + schema: "auth", + table: "user_login", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "ix_user_sessions_user_id", + schema: "tvnoms", + table: "user_sessions", + column: "user_id"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + schema: "auth", + table: "user_user_role", + column: "normalized_name", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "__movie_genres", + schema: "tvnoms"); + + migrationBuilder.DropTable( + name: "__show_genres", + schema: "tvnoms"); + + migrationBuilder.DropTable( + name: "clients", + schema: "tvnoms"); + + migrationBuilder.DropTable( + name: "identity_user", + schema: "auth"); + + migrationBuilder.DropTable( + name: "identity_user_base", + schema: "auth"); + + migrationBuilder.DropTable( + name: "role_claim", + schema: "auth"); + + migrationBuilder.DropTable( + name: "roles", + schema: "auth"); + + migrationBuilder.DropTable( + name: "user_claim", + schema: "auth"); + + migrationBuilder.DropTable( + name: "user_identity_role", + schema: "auth"); + + migrationBuilder.DropTable( + name: "user_login", + schema: "auth"); + + migrationBuilder.DropTable( + name: "user_sessions", + schema: "tvnoms"); + + migrationBuilder.DropTable( + name: "user_token", + schema: "auth"); + + migrationBuilder.DropTable( + name: "movies", + schema: "tvnoms"); + + migrationBuilder.DropTable( + name: "genres", + schema: "tvnoms"); + + migrationBuilder.DropTable( + name: "shows", + schema: "tvnoms"); + + migrationBuilder.DropTable( + name: "user_user_role", + schema: "auth"); + + migrationBuilder.DropTable( + name: "user", + schema: "auth"); + + migrationBuilder.DropTable( + name: "media", + schema: "tvnoms"); + } + } +} diff --git a/src/tvnoms-server/TvNoms.Data/Migrations/AppDbContextModelSnapshot.cs b/src/tvnoms-server/TvNoms.Data/Migrations/AppDbContextModelSnapshot.cs new file mode 100644 index 0000000..e1d17cc --- /dev/null +++ b/src/tvnoms-server/TvNoms.Data/Migrations/AppDbContextModelSnapshot.cs @@ -0,0 +1,881 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using TvNoms.Server.Data; + +#nullable disable + +namespace TvNoms.Server.Data.Migrations +{ + [DbContext(typeof(AppDbContext))] + partial class AppDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("tvnoms") + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("GenreMovie", b => + { + b.Property("GenresId") + .HasColumnType("uuid") + .HasColumnName("genres_id"); + + b.Property("MovieId") + .HasColumnType("uuid") + .HasColumnName("movie_id"); + + b.HasKey("GenresId", "MovieId") + .HasName("pk___movie_genres"); + + b.HasIndex("MovieId") + .HasDatabaseName("ix___movie_genres_movie_id"); + + b.ToTable("__movie_genres", "tvnoms"); + }); + + modelBuilder.Entity("GenreShow", b => + { + b.Property("GenresId") + .HasColumnType("uuid") + .HasColumnName("genres_id"); + + b.Property("ShowId") + .HasColumnType("uuid") + .HasColumnName("show_id"); + + b.HasKey("GenresId", "ShowId") + .HasName("pk___show_genres"); + + b.HasIndex("ShowId") + .HasDatabaseName("ix___show_genres_show_id"); + + b.ToTable("__show_genres", "tvnoms"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("name"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_name"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("user_user_role", "auth"); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text") + .HasColumnName("claim_type"); + + b.Property("ClaimValue") + .HasColumnType("text") + .HasColumnName("claim_value"); + + b.Property("RoleId") + .HasColumnType("uuid") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_role_claim"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_role_claim_role_id"); + + b.ToTable("role_claim", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("text") + .HasColumnName("id"); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasColumnName("access_failed_count"); + + b.Property("ConcurrencyStamp") + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Email") + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasColumnName("email_confirmed"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasColumnName("lockout_enabled"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("lockout_end"); + + b.Property("NormalizedEmail") + .HasColumnType("text") + .HasColumnName("normalized_email"); + + b.Property("NormalizedUserName") + .HasColumnType("text") + .HasColumnName("normalized_user_name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PhoneNumber") + .HasColumnType("text") + .HasColumnName("phone_number"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasColumnName("phone_number_confirmed"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasColumnName("security_stamp"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasColumnName("two_factor_enabled"); + + b.Property("UserName") + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("pk_identity_user_base"); + + b.ToTable("identity_user_base", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasColumnName("access_failed_count"); + + b.Property("ConcurrencyStamp") + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Email") + .HasColumnType("text") + .HasColumnName("email"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasColumnName("email_confirmed"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasColumnName("lockout_enabled"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("lockout_end"); + + b.Property("NormalizedEmail") + .HasColumnType("text") + .HasColumnName("normalized_email"); + + b.Property("NormalizedUserName") + .HasColumnType("text") + .HasColumnName("normalized_user_name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PhoneNumber") + .HasColumnType("text") + .HasColumnName("phone_number"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasColumnName("phone_number_confirmed"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasColumnName("security_stamp"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasColumnName("two_factor_enabled"); + + b.Property("UserName") + .HasColumnType("text") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("pk_identity_user"); + + b.ToTable("identity_user", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text") + .HasColumnName("claim_type"); + + b.Property("ClaimValue") + .HasColumnType("text") + .HasColumnName("claim_value"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_user_claim"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_user_claim_user_id"); + + b.ToTable("user_claim", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text") + .HasColumnName("login_provider"); + + b.Property("ProviderKey") + .HasColumnType("text") + .HasColumnName("provider_key"); + + b.Property("ProviderDisplayName") + .HasColumnType("text") + .HasColumnName("provider_display_name"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("LoginProvider", "ProviderKey") + .HasName("pk_user_login"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_user_login_user_id"); + + b.ToTable("user_login", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("RoleId") + .HasColumnType("uuid") + .HasColumnName("role_id"); + + b.HasKey("UserId", "RoleId") + .HasName("pk_user_identity_role"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_user_identity_role_role_id"); + + b.ToTable("user_identity_role", "auth"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.Property("LoginProvider") + .HasColumnType("text") + .HasColumnName("login_provider"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Value") + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("UserId", "LoginProvider", "Name") + .HasName("pk_user_token"); + + b.ToTable("user_token", "auth"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Active") + .HasColumnType("boolean") + .HasColumnName("active"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("connection_id"); + + b.Property("ConnectionTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("connection_time"); + + b.Property("DateCreated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateUpdated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_updated"); + + b.Property("DeviceId") + .HasColumnType("text") + .HasColumnName("device_id"); + + b.Property("IpAddress") + .HasColumnType("text") + .HasColumnName("ip_address"); + + b.Property("UserAgent") + .HasColumnType("text") + .HasColumnName("user_agent"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_clients"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_clients_user_id"); + + b.ToTable("clients", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateCreated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateUpdated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_updated"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasColumnName("description"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_genres"); + + b.HasIndex("Name") + .IsUnique() + .HasDatabaseName("ix_genres_name"); + + b.ToTable("genres", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Media", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("text") + .HasColumnName("content_type"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("created_at"); + + b.Property("DateCreated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateUpdated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_updated"); + + b.Property("Height") + .HasColumnType("integer") + .HasColumnName("height"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("Path") + .IsRequired() + .HasColumnType("text") + .HasColumnName("path"); + + b.Property("Size") + .HasColumnType("bigint") + .HasColumnName("size"); + + b.Property("Type") + .HasColumnType("integer") + .HasColumnName("type"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("updated_at"); + + b.Property("Width") + .HasColumnType("integer") + .HasColumnName("width"); + + b.HasKey("Id") + .HasName("pk_media"); + + b.ToTable("media", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Movie", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateCreated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateUpdated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_updated"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text") + .HasColumnName("title"); + + b.HasKey("Id") + .HasName("pk_movies"); + + b.ToTable("movies", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Show", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("DateCreated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created"); + + b.Property("DateUpdated") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("timestamp with time zone") + .HasColumnName("date_updated"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text") + .HasColumnName("title"); + + b.HasKey("Id") + .HasName("pk_shows"); + + b.ToTable("shows", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccessFailedCount") + .HasColumnType("integer") + .HasColumnName("access_failed_count"); + + b.Property("Active") + .HasColumnType("boolean") + .HasColumnName("active"); + + b.Property("AvatarId") + .HasColumnType("uuid") + .HasColumnName("avatar_id"); + + b.Property("Bio") + .HasColumnType("text") + .HasColumnName("bio"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text") + .HasColumnName("concurrency_stamp"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("email"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean") + .HasColumnName("email_confirmed"); + + b.Property("EmailRequired") + .HasColumnType("boolean") + .HasColumnName("email_required"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("first_name"); + + b.Property("LastActiveAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_active_at"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("last_name"); + + b.Property("Location") + .HasColumnType("text") + .HasColumnName("location"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean") + .HasColumnName("lockout_enabled"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("lockout_end"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_email"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("normalized_user_name"); + + b.Property("PasswordHash") + .HasColumnType("text") + .HasColumnName("password_hash"); + + b.Property("PhoneNumber") + .HasColumnType("text") + .HasColumnName("phone_number"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean") + .HasColumnName("phone_number_confirmed"); + + b.Property("PhoneNumberRequired") + .HasColumnType("boolean") + .HasColumnName("phone_number_required"); + + b.Property("SecurityStamp") + .HasColumnType("text") + .HasColumnName("security_stamp"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean") + .HasColumnName("two_factor_enabled"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("user_name"); + + b.HasKey("Id") + .HasName("pk_user"); + + b.HasIndex("AvatarId") + .HasDatabaseName("ix_user_avatar_id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("user", "auth"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.UserSession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("AccessTokenExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("access_token_expires_at"); + + b.Property("AccessTokenHash") + .IsRequired() + .HasColumnType("text") + .HasColumnName("access_token_hash"); + + b.Property("RefreshTokenExpiresAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("refresh_token_expires_at"); + + b.Property("RefreshTokenHash") + .IsRequired() + .HasColumnType("text") + .HasColumnName("refresh_token_hash"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasColumnName("user_id"); + + b.HasKey("Id") + .HasName("pk_user_sessions"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_user_sessions_user_id"); + + b.ToTable("user_sessions", "tvnoms"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Role", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityRole"); + + b.ToTable("roles", "auth"); + }); + + modelBuilder.Entity("GenreMovie", b => + { + b.HasOne("TvNoms.Core.Entities.Genre", null) + .WithMany() + .HasForeignKey("GenresId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk___movie_genres_genres_genres_id"); + + b.HasOne("TvNoms.Core.Entities.Movie", null) + .WithMany() + .HasForeignKey("MovieId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk___movie_genres_movies_movie_id"); + }); + + modelBuilder.Entity("GenreShow", b => + { + b.HasOne("TvNoms.Core.Entities.Genre", null) + .WithMany() + .HasForeignKey("GenresId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk___show_genres_genres_genres_id"); + + b.HasOne("TvNoms.Core.Entities.Show", null) + .WithMany() + .HasForeignKey("ShowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk___show_genres_shows_show_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_role_claim_user_user_role_role_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("TvNoms.Core.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_claim_user_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("TvNoms.Core.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_login_user_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_identity_role_user_user_role_role_id"); + + b.HasOne("TvNoms.Core.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_identity_role_user_user_id"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("TvNoms.Core.Entities.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_token_user_user_id"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Client", b => + { + b.HasOne("TvNoms.Core.Entities.User", "User") + .WithMany("Clients") + .HasForeignKey("UserId") + .HasConstraintName("fk_clients_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.User", b => + { + b.HasOne("TvNoms.Core.Entities.Media", "Avatar") + .WithMany() + .HasForeignKey("AvatarId") + .HasConstraintName("fk_user_media_avatar_id"); + + b.Navigation("Avatar"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.UserSession", b => + { + b.HasOne("TvNoms.Core.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_sessions_user_user_id"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.Role", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithOne() + .HasForeignKey("TvNoms.Core.Entities.Role", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_roles_user_user_role_id"); + }); + + modelBuilder.Entity("TvNoms.Core.Entities.User", b => + { + b.Navigation("Clients"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/tvnoms-server/TvNoms.Infrastructure/Identity/ServiceCollectionExtensions.cs b/src/tvnoms-server/TvNoms.Infrastructure/Identity/ServiceCollectionExtensions.cs index 3049405..5a84f36 100644 --- a/src/tvnoms-server/TvNoms.Infrastructure/Identity/ServiceCollectionExtensions.cs +++ b/src/tvnoms-server/TvNoms.Infrastructure/Identity/ServiceCollectionExtensions.cs @@ -13,6 +13,7 @@ public static class ServiceCollectionExtensions { public static IServiceCollection AddWebAppCors(this IServiceCollection services, IConfiguration config) { services.AddCors(options => { options.AddPolicy("WebAppCors", policy => { + // options.AddDefaultPolicy(policy => { var allowedOrigins = config.GetSection("AllowedOrigins")?.Get() ?? Array.Empty(); @@ -21,8 +22,9 @@ public static class ServiceCollectionExtensions { .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials() - .WithExposedHeaders("Content-Disposition") - .SetPreflightMaxAge(TimeSpan.FromMinutes(10)); + // .WithExposedHeaders("Content-Disposition") + // .SetPreflightMaxAge(TimeSpan.FromMinutes(10)) + ; }); }); return services; diff --git a/src/tvnoms-server/TvNoms.Infrastructure/Jobs/Media/TheTvDb/GetTrendingTvShowsJob.cs b/src/tvnoms-server/TvNoms.Infrastructure/Jobs/Media/TheTvDb/GetTrendingTvShowsJob.cs index 060f9d2..e95915c 100644 --- a/src/tvnoms-server/TvNoms.Infrastructure/Jobs/Media/TheTvDb/GetTrendingTvShowsJob.cs +++ b/src/tvnoms-server/TvNoms.Infrastructure/Jobs/Media/TheTvDb/GetTrendingTvShowsJob.cs @@ -16,7 +16,7 @@ public class GetTrendingTvShowsJob(IShowLookupService lookupService, ILogger>(token); - return results; } }