diff --git a/Selector.Model/Migrations/20241220180955_net9.Designer.cs b/Selector.Model/Migrations/20241220180955_net9.Designer.cs
new file mode 100644
index 0000000..41bbd7f
--- /dev/null
+++ b/Selector.Model/Migrations/20241220180955_net9.Designer.cs
@@ -0,0 +1,491 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using Selector.Model;
+
+#nullable disable
+
+namespace Selector.Model.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20241220180955_net9")]
+ partial class net9
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("Npgsql:CollationDefinition:case_insensitive", "en-u-ks-primary,en-u-ks-primary,icu,False")
+ .HasAnnotation("ProductVersion", "9.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = "00c64c0a-3387-4933-9575-83443fa9092b",
+ Name = "Admin",
+ NormalizedName = "ADMIN"
+ });
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("text");
+
+ b.Property("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property("RoleId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("text");
+
+ b.Property("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property("ProviderKey")
+ .HasColumnType("text");
+
+ b.Property("ProviderDisplayName")
+ .HasColumnType("text");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("text");
+
+ b.Property("RoleId")
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("text");
+
+ b.Property("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .HasColumnType("text");
+
+ b.Property("Value")
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens", (string)null);
+ });
+
+ modelBuilder.Entity("Selector.Model.AlbumLastfmSpotifyMapping", b =>
+ {
+ b.Property("SpotifyUri")
+ .HasColumnType("text");
+
+ b.Property("LastfmAlbumName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.Property("LastfmArtistName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.HasKey("SpotifyUri");
+
+ b.ToTable("AlbumMapping");
+ });
+
+ modelBuilder.Entity("Selector.Model.ApplicationUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("AccessFailedCount")
+ .HasColumnType("integer");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("EmailConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property("LastFmUsername")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.Property("LockoutEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("PasswordHash")
+ .HasColumnType("text");
+
+ b.Property("PhoneNumber")
+ .HasColumnType("text");
+
+ b.Property("PhoneNumberConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property("SaveScrobbles")
+ .HasColumnType("boolean");
+
+ b.Property("SecurityStamp")
+ .HasColumnType("text");
+
+ b.Property("SpotifyAccessToken")
+ .HasColumnType("text");
+
+ b.Property("SpotifyIsLinked")
+ .HasColumnType("boolean");
+
+ b.Property("SpotifyLastRefresh")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("SpotifyRefreshToken")
+ .HasColumnType("text");
+
+ b.Property("SpotifyTokenExpiry")
+ .HasColumnType("integer");
+
+ b.Property("TwoFactorEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex");
+
+ b.ToTable("AspNetUsers", (string)null);
+ });
+
+ modelBuilder.Entity("Selector.Model.ArtistLastfmSpotifyMapping", b =>
+ {
+ b.Property("SpotifyUri")
+ .HasColumnType("text");
+
+ b.Property("LastfmArtistName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.HasKey("SpotifyUri");
+
+ b.ToTable("ArtistMapping");
+ });
+
+ modelBuilder.Entity("Selector.Model.SpotifyListen", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AlbumName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.Property("ArtistName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.Property("PlayedDuration")
+ .HasColumnType("integer");
+
+ b.Property("Timestamp")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("TrackName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.Property("TrackUri")
+ .HasColumnType("text");
+
+ b.Property("UserId")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("SpotifyListen");
+ });
+
+ modelBuilder.Entity("Selector.Model.TrackLastfmSpotifyMapping", b =>
+ {
+ b.Property("SpotifyUri")
+ .HasColumnType("text");
+
+ b.Property("LastfmArtistName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.Property("LastfmTrackName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.HasKey("SpotifyUri");
+
+ b.ToTable("TrackMapping");
+ });
+
+ modelBuilder.Entity("Selector.Model.UserScrobble", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AlbumArtistName")
+ .HasColumnType("text");
+
+ b.Property("AlbumName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.Property("ArtistName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.Property("Timestamp")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("TrackName")
+ .HasColumnType("text")
+ .UseCollation("case_insensitive");
+
+ b.Property("UserId")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Scrobble");
+ });
+
+ modelBuilder.Entity("Selector.Model.Watcher", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Watcher");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("Selector.Model.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("Selector.Model.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Selector.Model.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.HasOne("Selector.Model.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Selector.Model.SpotifyListen", b =>
+ {
+ b.HasOne("Selector.Model.ApplicationUser", "User")
+ .WithMany()
+ .HasForeignKey("UserId");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Selector.Model.UserScrobble", b =>
+ {
+ b.HasOne("Selector.Model.ApplicationUser", "User")
+ .WithMany("Scrobbles")
+ .HasForeignKey("UserId");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Selector.Model.Watcher", b =>
+ {
+ b.HasOne("Selector.Model.ApplicationUser", "User")
+ .WithMany("Watchers")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Selector.Model.ApplicationUser", b =>
+ {
+ b.Navigation("Scrobbles");
+
+ b.Navigation("Watchers");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Selector.Model/Migrations/20241220180955_net9.cs b/Selector.Model/Migrations/20241220180955_net9.cs
new file mode 100644
index 0000000..65ba1dc
--- /dev/null
+++ b/Selector.Model/Migrations/20241220180955_net9.cs
@@ -0,0 +1,32 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Selector.Model.Migrations
+{
+ ///
+ public partial class net9 : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.UpdateData(
+ table: "AspNetRoles",
+ keyColumn: "Id",
+ keyValue: "00c64c0a-3387-4933-9575-83443fa9092b",
+ column: "ConcurrencyStamp",
+ value: null);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.UpdateData(
+ table: "AspNetRoles",
+ keyColumn: "Id",
+ keyValue: "00c64c0a-3387-4933-9575-83443fa9092b",
+ column: "ConcurrencyStamp",
+ value: "4b4a37c7-cc65-485a-ac0e-d88ef6dede78");
+ }
+ }
+}
diff --git a/Selector.Model/Migrations/ApplicationDbContextModelSnapshot.cs b/Selector.Model/Migrations/ApplicationDbContextModelSnapshot.cs
index d296389..632ed70 100644
--- a/Selector.Model/Migrations/ApplicationDbContextModelSnapshot.cs
+++ b/Selector.Model/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -18,7 +18,7 @@ namespace Selector.Model.Migrations
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:case_insensitive", "en-u-ks-primary,en-u-ks-primary,icu,False")
- .HasAnnotation("ProductVersion", "6.0.9")
+ .HasAnnotation("ProductVersion", "9.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
@@ -52,7 +52,6 @@ namespace Selector.Model.Migrations
new
{
Id = "00c64c0a-3387-4933-9575-83443fa9092b",
- ConcurrencyStamp = "4b4a37c7-cc65-485a-ac0e-d88ef6dede78",
Name = "Admin",
NormalizedName = "ADMIN"
});