Changed design language. Added editions, better support for authors. Base for file handling

This commit is contained in:
2026-03-28 15:17:20 +02:00
parent cbd7f52535
commit 5acde17a53
84 changed files with 5861 additions and 1983 deletions
@@ -0,0 +1,532 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using PageManager.Api.Data;
#nullable disable
namespace PageManager.Api.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20260329000000_AddBookFiles")]
partial class AddBookFiles
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("PageManager.Api.Data.Models.Author", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Bio")
.HasColumnType("text")
.HasColumnName("bio");
b.Property<int?>("BornYear")
.HasColumnType("integer")
.HasColumnName("born_year");
b.Property<int?>("HardcoverId")
.HasColumnType("integer")
.HasColumnName("hardcover_id");
b.Property<string>("ImageUrl")
.HasColumnType("text")
.HasColumnName("image_url");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Slug")
.HasColumnType("text")
.HasColumnName("slug");
b.HasKey("Id")
.HasName("pk_authors");
b.ToTable("authors", (string)null);
});
modelBuilder.Entity("PageManager.Api.Data.Models.Book", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Color")
.IsRequired()
.HasColumnType("text")
.HasColumnName("color");
b.Property<string>("CoverUrl")
.HasColumnType("text")
.HasColumnName("cover_url");
b.Property<string>("Description")
.HasColumnType("text")
.HasColumnName("description");
b.PrimitiveCollection<string[]>("Formats")
.IsRequired()
.HasColumnType("text[]")
.HasColumnName("formats");
b.PrimitiveCollection<string[]>("Genres")
.IsRequired()
.HasColumnType("text[]")
.HasColumnName("genres");
b.Property<int?>("HardcoverId")
.HasColumnType("integer")
.HasColumnName("hardcover_id");
b.Property<string>("Isbn")
.HasColumnType("text")
.HasColumnName("isbn");
b.Property<int?>("Pages")
.HasColumnType("integer")
.HasColumnName("pages");
b.Property<string>("Publisher")
.HasColumnType("text")
.HasColumnName("publisher");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("text")
.HasColumnName("title");
b.Property<int?>("Year")
.HasColumnType("integer")
.HasColumnName("year");
b.HasKey("Id")
.HasName("pk_books");
b.HasIndex("HardcoverId")
.HasDatabaseName("ix_books_hardcover_id");
b.HasIndex("Isbn")
.HasDatabaseName("ix_books_isbn");
b.ToTable("books", (string)null);
});
modelBuilder.Entity("PageManager.Api.Data.Models.BookAuthor", b =>
{
b.Property<int>("BookId")
.HasColumnType("integer")
.HasColumnName("book_id");
b.Property<int>("AuthorId")
.HasColumnType("integer")
.HasColumnName("author_id");
b.Property<string>("Role")
.IsRequired()
.HasColumnType("text")
.HasColumnName("role");
b.HasKey("BookId", "AuthorId")
.HasName("pk_book_authors");
b.HasIndex("AuthorId")
.HasDatabaseName("ix_book_authors_author_id");
b.ToTable("book_authors", (string)null);
});
modelBuilder.Entity("PageManager.Api.Data.Models.BookFile", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("AddedAt")
.HasColumnType("timestamp with time zone")
.HasColumnName("added_at");
b.Property<int?>("BookId")
.HasColumnType("integer")
.HasColumnName("book_id");
b.Property<int?>("EditionId")
.HasColumnType("integer")
.HasColumnName("edition_id");
b.Property<string>("Filename")
.IsRequired()
.HasColumnType("text")
.HasColumnName("filename");
b.Property<string>("Format")
.IsRequired()
.HasColumnType("text")
.HasColumnName("format")
.HasConversion<string>();
b.Property<string>("Hash")
.HasColumnType("text")
.HasColumnName("hash");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("text")
.HasColumnName("path");
b.Property<long>("SizeBytes")
.HasColumnType("bigint")
.HasColumnName("size_bytes");
b.Property<string>("SourceId")
.HasColumnType("text")
.HasColumnName("source_id");
b.HasKey("Id")
.HasName("pk_book_files");
b.HasIndex("BookId")
.HasDatabaseName("ix_book_files_book_id");
b.HasIndex("EditionId")
.HasDatabaseName("ix_book_files_edition_id");
b.HasIndex("Hash")
.HasDatabaseName("ix_book_files_hash");
b.HasIndex("SourceId")
.HasDatabaseName("ix_book_files_source_id");
b.ToTable("book_files", (string)null);
});
modelBuilder.Entity("PageManager.Api.Data.Models.Edition", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("BookId")
.HasColumnType("integer")
.HasColumnName("book_id");
b.Property<string>("Asin")
.HasColumnType("text")
.HasColumnName("asin");
b.Property<int?>("AudioSeconds")
.HasColumnType("integer")
.HasColumnName("audio_seconds");
b.Property<string>("CoverColor")
.HasColumnType("text")
.HasColumnName("cover_color");
b.Property<string>("CoverUrl")
.HasColumnType("text")
.HasColumnName("cover_url");
b.Property<string>("EditionFormat")
.HasColumnType("text")
.HasColumnName("edition_format");
b.Property<string>("Isbn")
.HasColumnType("text")
.HasColumnName("isbn");
b.Property<string>("Language")
.HasColumnType("text")
.HasColumnName("language");
b.Property<string>("LanguageCode")
.HasColumnType("text")
.HasColumnName("language_code");
b.Property<int?>("Pages")
.HasColumnType("integer")
.HasColumnName("pages");
b.Property<string>("Publisher")
.HasColumnType("text")
.HasColumnName("publisher");
b.Property<string>("ReadingFormat")
.HasColumnType("text")
.HasColumnName("reading_format")
.HasConversion<string>();
b.Property<int?>("ReleaseYear")
.HasColumnType("integer")
.HasColumnName("release_year");
b.HasKey("Id")
.HasName("pk_editions");
b.HasIndex("BookId")
.HasDatabaseName("ix_editions_book_id");
b.ToTable("editions", (string)null);
});
modelBuilder.Entity("PageManager.Api.Data.Models.ImportQueueItem", b =>
{
b.Property<string>("Id")
.HasColumnType("text")
.HasColumnName("id");
b.Property<long>("DownloadedBytes")
.HasColumnType("bigint")
.HasColumnName("downloaded_bytes");
b.Property<string>("Error")
.HasColumnType("text")
.HasColumnName("error");
b.Property<string>("Filename")
.IsRequired()
.HasColumnType("text")
.HasColumnName("filename");
b.Property<long>("SizeBytes")
.HasColumnType("bigint")
.HasColumnName("size_bytes");
b.Property<string>("Source")
.IsRequired()
.HasColumnType("text")
.HasColumnName("source");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("text")
.HasColumnName("status");
b.HasKey("Id")
.HasName("pk_import_queue_items");
b.ToTable("import_queue_items", (string)null);
});
modelBuilder.Entity("PageManager.Api.Data.Models.ImportSource", b =>
{
b.Property<string>("Id")
.HasColumnType("text")
.HasColumnName("id");
b.Property<bool>("Enabled")
.HasColumnType("boolean")
.HasColumnName("enabled");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Path")
.IsRequired()
.HasColumnType("text")
.HasColumnName("path");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text")
.HasColumnName("type");
b.HasKey("Id")
.HasName("pk_import_sources");
b.ToTable("import_sources", (string)null);
});
modelBuilder.Entity("PageManager.Api.Data.Models.Series", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text")
.HasColumnName("type");
b.HasKey("Id")
.HasName("pk_series");
b.ToTable("series", (string)null);
});
modelBuilder.Entity("PageManager.Api.Data.Models.SeriesEntry", b =>
{
b.Property<int>("SeriesId")
.HasColumnType("integer")
.HasColumnName("series_id");
b.Property<int>("BookId")
.HasColumnType("integer")
.HasColumnName("book_id");
b.Property<string>("Arc")
.HasColumnType("text")
.HasColumnName("arc");
b.Property<double>("Position")
.HasColumnType("double precision")
.HasColumnName("position");
b.HasKey("SeriesId", "BookId")
.HasName("pk_series_entries");
b.HasIndex("BookId")
.HasDatabaseName("ix_series_entries_book_id");
b.ToTable("series_entries", (string)null);
});
modelBuilder.Entity("PageManager.Api.Data.Models.BookAuthor", b =>
{
b.HasOne("PageManager.Api.Data.Models.Author", "Author")
.WithMany("BookAuthors")
.HasForeignKey("AuthorId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_book_authors_authors_author_id");
b.HasOne("PageManager.Api.Data.Models.Book", "Book")
.WithMany("BookAuthors")
.HasForeignKey("BookId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_book_authors_books_book_id");
b.Navigation("Author");
b.Navigation("Book");
});
modelBuilder.Entity("PageManager.Api.Data.Models.BookFile", b =>
{
b.HasOne("PageManager.Api.Data.Models.Book", "Book")
.WithMany("BookFiles")
.HasForeignKey("BookId")
.OnDelete(DeleteBehavior.SetNull)
.HasConstraintName("fk_book_files_books_book_id");
b.HasOne("PageManager.Api.Data.Models.Edition", "Edition")
.WithMany("BookFiles")
.HasForeignKey("EditionId")
.OnDelete(DeleteBehavior.SetNull)
.HasConstraintName("fk_book_files_editions_edition_id");
b.HasOne("PageManager.Api.Data.Models.ImportSource", "Source")
.WithMany()
.HasForeignKey("SourceId")
.OnDelete(DeleteBehavior.SetNull)
.HasConstraintName("fk_book_files_import_sources_source_id");
b.Navigation("Book");
b.Navigation("Edition");
b.Navigation("Source");
});
modelBuilder.Entity("PageManager.Api.Data.Models.Edition", b =>
{
b.HasOne("PageManager.Api.Data.Models.Book", "Book")
.WithMany("Editions")
.HasForeignKey("BookId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_editions_books_book_id");
b.Navigation("Book");
});
modelBuilder.Entity("PageManager.Api.Data.Models.SeriesEntry", b =>
{
b.HasOne("PageManager.Api.Data.Models.Book", "Book")
.WithMany("SeriesEntries")
.HasForeignKey("BookId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_series_entries_books_book_id");
b.HasOne("PageManager.Api.Data.Models.Series", "Series")
.WithMany("Entries")
.HasForeignKey("SeriesId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_series_entries_series_series_id");
b.Navigation("Book");
b.Navigation("Series");
});
modelBuilder.Entity("PageManager.Api.Data.Models.Author", b =>
{
b.Navigation("BookAuthors");
});
modelBuilder.Entity("PageManager.Api.Data.Models.Book", b =>
{
b.Navigation("BookAuthors");
b.Navigation("BookFiles");
b.Navigation("Editions");
b.Navigation("SeriesEntries");
});
modelBuilder.Entity("PageManager.Api.Data.Models.Edition", b =>
{
b.Navigation("BookFiles");
b.Navigation("Book");
});
modelBuilder.Entity("PageManager.Api.Data.Models.Series", b =>
{
b.Navigation("Entries");
});
#pragma warning restore 612, 618
}
}
}