Compare commits
6 Commits
6a83de1f5d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| b3102c2660 | |||
| 6b5c5d0d3b | |||
| adbc3a28d6 | |||
| f71283d617 | |||
| ca78d6ace4 | |||
| 400faa2fc3 |
@@ -0,0 +1,171 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OakArchive.Entities.CardMarket;
|
||||
using OakArchive.Entities.Cards;
|
||||
using OakArchive.Entities.Collection;
|
||||
using OakArchive.Entities.Grading;
|
||||
using OakArchive.Entities.Serie;
|
||||
using OakArchive.Entities.Set;
|
||||
using OakArchive.Entities.TCGdex;
|
||||
using OakArchive.Entities.User;
|
||||
|
||||
namespace OakArchive.Database;
|
||||
|
||||
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole<Guid>, Guid>
|
||||
{
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<Settings> Settings { get; set; } = null!;
|
||||
public DbSet<Collection> Collections { get; set; } = null!;
|
||||
public DbSet<CollectedCard> CollectedCards { get; set; } = null!;
|
||||
public DbSet<Grading> Gradings { get; set; } = null!;
|
||||
public DbSet<TcgDexCardInfo> TcgDexCardInfos { get; set; } = null!;
|
||||
public DbSet<TcgDexSetInfo> TcgDexSetInfos { get; set; } = null!;
|
||||
public DbSet<TcgDexSeriesInfo> TcgDexSeriesInfos { get; set; } = null!;
|
||||
public DbSet<Serie> Series { get; set; } = null!;
|
||||
public DbSet<Set> Sets { get; set; } = null!;
|
||||
public DbSet<Legal> Legals { get; set; } = null!;
|
||||
public DbSet<CardCount> CardCounts { get; set; } = null!;
|
||||
public DbSet<Card> Cards { get; set; } = null!;
|
||||
public DbSet<Attack> Attacks { get; set; } = null!;
|
||||
public DbSet<Weakness> Weaknesses { get; set; } = null!;
|
||||
public DbSet<CardMarketSetInfo> CardMarketSetInfos { get; set; } = null!;
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
// 1. Basis-Mapping für ASP.NET Core Identity (Pflicht!)
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
#region User & Settings
|
||||
|
||||
modelBuilder.Entity<ApplicationUser>(entity =>
|
||||
{
|
||||
// Konfiguration für das private Feld 'DefaultCollection' als Backing Field
|
||||
entity.Property<Guid>("DefaultCollectionId");
|
||||
|
||||
entity.HasOne<Collection>()
|
||||
.WithMany()
|
||||
.HasForeignKey("DefaultCollectionId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
// n:m Beziehung zwischen Usern und Collections (Members)
|
||||
entity.HasMany(u => u.Collections)
|
||||
.WithMany(c => c.Members)
|
||||
.UsingEntity(j => j.ToTable("UserCollections"));
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Settings>()
|
||||
.HasOne(s => s.User)
|
||||
.WithOne(u => u.Settings)
|
||||
.HasForeignKey<Settings>(s => s.UserId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 1:1 TCGdex & CardMarket Mapping
|
||||
|
||||
// EF Core mitgeteilt, auf welcher Seite der FK physisch liegt
|
||||
modelBuilder.Entity<Card>()
|
||||
.HasOne(c => c.TcgDexCardInfo)
|
||||
.WithOne(t => t.Card)
|
||||
.HasForeignKey<TcgDexCardInfo>(t => t.CardId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<Set>()
|
||||
.HasOne(s => s.SetInfo)
|
||||
.WithOne(t => t.Set)
|
||||
.HasForeignKey<TcgDexSetInfo>(t => t.SetIdRef)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<Serie>()
|
||||
.HasOne(s => s.TcgDexSeriesInfo)
|
||||
.WithOne(t => t.Series)
|
||||
.HasForeignKey<TcgDexSeriesInfo>(t => t.SeriesIdRef)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<Set>()
|
||||
.HasOne(s => s.CardCount)
|
||||
.WithOne(c => c.Set)
|
||||
.HasForeignKey<CardCount>(c => c.SetId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<Set>()
|
||||
.HasOne(s => s.CardMarketSetInfo)
|
||||
.WithOne(cms => cms.Set)
|
||||
.HasForeignKey<CardMarketSetInfo>(cms => cms.SetId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
// Auflösung der geteilten Legal-Tabelle
|
||||
modelBuilder.Entity<Legal>(entity =>
|
||||
{
|
||||
entity.HasOne(l => l.Set)
|
||||
.WithOne(s => s.Legal)
|
||||
.HasForeignKey<Legal>(l => l.SetId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
entity.HasOne(l => l.Card)
|
||||
.WithOne(c => c.Legal)
|
||||
.HasForeignKey<Legal>(l => l.CardId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
#endregion
|
||||
|
||||
#region Postgres JSONB Columns
|
||||
|
||||
modelBuilder.Entity<Card>(entity =>
|
||||
{
|
||||
entity.HasOne(c => c.Set)
|
||||
.WithMany(s => s.Cards)
|
||||
.HasForeignKey(c => c.SetId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
// Native .NET Listen als JSONB in Postgres speichern
|
||||
entity.Property(c => c.Variants).HasColumnType("jsonb");
|
||||
entity.Property(c => c.Types).HasColumnType("jsonb");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Attack>(entity =>
|
||||
{
|
||||
entity.HasOne(a => a.Card)
|
||||
.WithMany(c => c.Attacks)
|
||||
.HasForeignKey(a => a.CardId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
entity.Property(a => a.Cost).HasColumnType("jsonb");
|
||||
});
|
||||
|
||||
#endregion
|
||||
|
||||
#region CollectedCard & Grading
|
||||
|
||||
modelBuilder.Entity<CollectedCard>(entity =>
|
||||
{
|
||||
entity.HasOne(cc => cc.Collection)
|
||||
.WithMany(c => c.Cards)
|
||||
.HasForeignKey(cc => cc.CollectionId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
entity.HasOne(cc => cc.Card)
|
||||
.WithMany()
|
||||
.HasForeignKey(cc => cc.CardId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
entity.HasOne(cc => cc.ScannedBy)
|
||||
.WithMany()
|
||||
.HasForeignKey(cc => cc.ScannedById)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<Grading>()
|
||||
.HasOne(g => g.CollectedCard)
|
||||
.WithOne(cc => cc.Grading)
|
||||
.HasForeignKey<Grading>(g => g.CollectedCardId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using OakArchive.Entities.Cards;
|
||||
|
||||
namespace OakArchive.Entities.CardMarket;
|
||||
|
||||
public class CardMarketSetInfo
|
||||
{
|
||||
[Key] public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public string ExpansionId { get; set; } = string.Empty;
|
||||
|
||||
[ForeignKey(nameof(Set))] public Guid SetId { get; set; }
|
||||
public virtual Set.Set Set { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
|
||||
|
||||
namespace OakArchive.Entities.Cards;
|
||||
|
||||
public class Attack
|
||||
{
|
||||
[Key] public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public List<string> Cost { get; set; } = [];
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public int? Damage { get; set; }
|
||||
|
||||
public string Effect { get; set; } = string.Empty;
|
||||
|
||||
[ForeignKey(nameof(Card))] public Guid CardId { get; set; }
|
||||
public virtual Card Card { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using OakArchive.Entities.CardMarket;
|
||||
using OakArchive.Entities.Enums;
|
||||
using OakArchive.Entities.Set;
|
||||
using OakArchive.Entities.TCGdex;
|
||||
|
||||
namespace OakArchive.Entities.Cards;
|
||||
|
||||
public class Card
|
||||
{
|
||||
[Key] public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[Required] public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string Image { get; set; } = string.Empty;
|
||||
|
||||
public int CardNumber { get; set; } = 0;
|
||||
|
||||
public ulong PHash { get; set; } = 0;
|
||||
|
||||
public int? Hp { get; set; }
|
||||
|
||||
public int? Retreat { get; set; }
|
||||
|
||||
public string? TrainerType { get; set; }
|
||||
|
||||
public string? EnergyType { get; set; }
|
||||
|
||||
public string? Illustrator { get; set; }
|
||||
|
||||
public string? EvolveFrom { get; set; }
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
public string? RegulationMark { get; set; }
|
||||
|
||||
public Rarity? Rarity { get; set; }
|
||||
|
||||
public Category? Category { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")]
|
||||
public List<Variant>? Variants { get; set; }
|
||||
|
||||
[Column(TypeName = "jsonb")] public List<string>? Types { get; set; }
|
||||
|
||||
[ForeignKey(nameof(Set))] public Guid SetId { get; set; }
|
||||
public virtual Set.Set Set { get; set; } = null!;
|
||||
|
||||
public virtual TcgDexCardInfo TcgDexCardInfo { get; set; } = null!;
|
||||
|
||||
public virtual Legal? Legal { get; set; }
|
||||
|
||||
public virtual ICollection<Attack> Attacks { get; set; } = new List<Attack>();
|
||||
|
||||
public virtual ICollection<Weakness> Weaknesses { get; set; } = new List<Weakness>();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using OakArchive.Entities.Enums;
|
||||
using OakArchive.Entities.User;
|
||||
|
||||
namespace OakArchive.Entities.Cards;
|
||||
|
||||
public class CollectedCard
|
||||
{
|
||||
[Key] public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public Variant Variant { get; set; } = Variant.Normal;
|
||||
|
||||
public Condition Condition { get; set; } = Condition.Mint;
|
||||
|
||||
public int Count { get; set; } = 1;
|
||||
|
||||
public Language Language { get; set; } = Language.En;
|
||||
|
||||
public DateTime ScannedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[ForeignKey(nameof(ScannedBy))] public Guid ScannedById { get; set; }
|
||||
public ApplicationUser ScannedBy { get; set; } = null!;
|
||||
|
||||
[ForeignKey(nameof(Collection))] public Guid CollectionId { get; set; }
|
||||
public virtual Collection.Collection Collection { get; set; } = null!;
|
||||
|
||||
[ForeignKey(nameof(Card))] public Guid CardId { get; set; }
|
||||
public virtual Card Card { get; set; } = null!;
|
||||
|
||||
public virtual Grading.Grading? Grading { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace OakArchive.Entities.Cards;
|
||||
|
||||
public class Weakness
|
||||
{
|
||||
[Key] public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public string Type { get; set; } = string.Empty;
|
||||
|
||||
public string Value { get; set; } = string.Empty;
|
||||
|
||||
[ForeignKey(nameof(Card))] public Guid CardId { get; set; }
|
||||
public virtual Card Card { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using OakArchive.Entities.Cards;
|
||||
using OakArchive.Entities.User;
|
||||
|
||||
namespace OakArchive.Entities.Collection;
|
||||
|
||||
public class Collection
|
||||
{
|
||||
|
||||
[Key]
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
public Guid CreatedBy { get; set; } = Guid.Empty;
|
||||
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
public string InviteCode { get; set; } = string.Empty;
|
||||
|
||||
public bool IsPublic { get; set; } = false;
|
||||
|
||||
public virtual ICollection<ApplicationUser> Members { get; set; } = [];
|
||||
|
||||
public virtual ICollection<CollectedCard> Cards { get; set; } = [];
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Entities.Enums;
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum Category
|
||||
{
|
||||
[JsonPropertyName("Energy")]
|
||||
Energy,
|
||||
|
||||
[JsonPropertyName("Pokemon")]
|
||||
Pokemon,
|
||||
|
||||
[JsonPropertyName("Trainer")]
|
||||
Trainer
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace OakArchive.Entities.Enums;
|
||||
|
||||
public enum Condition
|
||||
{
|
||||
Mint = 0,
|
||||
NearMint = 1,
|
||||
Excellent = 2,
|
||||
Good = 3,
|
||||
LightPlayed = 4,
|
||||
Played = 5,
|
||||
Poor = 6
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace OakArchive.Entities.Enums;
|
||||
|
||||
public enum GradingCompany
|
||||
{
|
||||
PSA,
|
||||
BGS,
|
||||
CGC,
|
||||
APGrading,
|
||||
EGS,
|
||||
AOG,
|
||||
PCA,
|
||||
GSG,
|
||||
Other
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace OakArchive.Entities.Enums;
|
||||
|
||||
public enum Language
|
||||
{
|
||||
En,
|
||||
Fr,
|
||||
Es,
|
||||
Es_Mx,
|
||||
It,
|
||||
Pt,
|
||||
Pt_Br,
|
||||
Pt_Pt,
|
||||
De,
|
||||
Nl,
|
||||
Pl,
|
||||
Ru,
|
||||
Ja,
|
||||
Ko,
|
||||
Zh_Tw,
|
||||
Id,
|
||||
Th,
|
||||
Zh_Cn
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Entities.Enums;
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum Rarity
|
||||
{
|
||||
[JsonPropertyName("ACE SPEC Rare")]
|
||||
AceSpecRare,
|
||||
|
||||
[JsonPropertyName("Amazing Rare")]
|
||||
AmazingRare,
|
||||
|
||||
[JsonPropertyName("Black White Rare")]
|
||||
BlackWhiteRare,
|
||||
|
||||
[JsonPropertyName("Classic Collection")]
|
||||
ClassicCollection,
|
||||
|
||||
[JsonPropertyName("Common")]
|
||||
Common,
|
||||
|
||||
[JsonPropertyName("Crown")]
|
||||
Crown,
|
||||
|
||||
[JsonPropertyName("Double rare")]
|
||||
DoubleRare,
|
||||
|
||||
[JsonPropertyName("Four Diamond")]
|
||||
FourDiamond,
|
||||
|
||||
[JsonPropertyName("Full Art Trainer")]
|
||||
FullArtTrainer,
|
||||
|
||||
[JsonPropertyName("Holo Rare")]
|
||||
HoloRare,
|
||||
|
||||
[JsonPropertyName("Holo Rare V")]
|
||||
HoloRareV,
|
||||
|
||||
[JsonPropertyName("Holo Rare VMAX")]
|
||||
HoloRareVmax,
|
||||
|
||||
[JsonPropertyName("Holo Rare VSTAR")]
|
||||
HoloRareVstar,
|
||||
|
||||
[JsonPropertyName("Hyper rare")]
|
||||
HyperRare,
|
||||
|
||||
[JsonPropertyName("Illustration rare")]
|
||||
IllustrationRare,
|
||||
|
||||
[JsonPropertyName("LEGEND")]
|
||||
Legend,
|
||||
|
||||
[JsonPropertyName("Mega Hyper Rare")]
|
||||
MegaHyperRare,
|
||||
|
||||
[JsonPropertyName("None")]
|
||||
None,
|
||||
|
||||
[JsonPropertyName("One Diamond")]
|
||||
OneDiamond,
|
||||
|
||||
[JsonPropertyName("One Shiny")]
|
||||
OneShiny,
|
||||
|
||||
[JsonPropertyName("One Star")]
|
||||
OneStar,
|
||||
|
||||
[JsonPropertyName("Radiant Rare")]
|
||||
RadiantRare,
|
||||
|
||||
[JsonPropertyName("Rare")]
|
||||
Rare,
|
||||
|
||||
[JsonPropertyName("Rare Holo")]
|
||||
RareHolo,
|
||||
|
||||
[JsonPropertyName("Rare Holo LV.X")]
|
||||
RareHoloLvX,
|
||||
|
||||
[JsonPropertyName("Rare PRIME")]
|
||||
RarePrime,
|
||||
|
||||
[JsonPropertyName("Secret Rare")]
|
||||
SecretRare,
|
||||
|
||||
[JsonPropertyName("Shiny Ultra Rare")]
|
||||
ShinyUltraRare,
|
||||
|
||||
[JsonPropertyName("Shiny rare")]
|
||||
ShinyRare,
|
||||
|
||||
[JsonPropertyName("Shiny rare V")]
|
||||
ShinyRareV,
|
||||
|
||||
[JsonPropertyName("Shiny rare VMAX")]
|
||||
ShinyRareVmax,
|
||||
|
||||
[JsonPropertyName("Special illustration rare")]
|
||||
SpecialIllustrationRare,
|
||||
|
||||
[JsonPropertyName("Three Diamond")]
|
||||
ThreeDiamond,
|
||||
|
||||
[JsonPropertyName("Three Star")]
|
||||
ThreeStar,
|
||||
|
||||
[JsonPropertyName("Two Diamond")]
|
||||
TwoDiamond,
|
||||
|
||||
[JsonPropertyName("Two Shiny")]
|
||||
TwoShiny,
|
||||
|
||||
[JsonPropertyName("Two Star")]
|
||||
TwoStar,
|
||||
|
||||
[JsonPropertyName("Ultra Rare")]
|
||||
UltraRare,
|
||||
|
||||
[JsonPropertyName("Uncommon")]
|
||||
Uncommon
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Entities.Enums;
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum Stage
|
||||
{
|
||||
[JsonPropertyName("BREAK")]
|
||||
Break,
|
||||
|
||||
[JsonPropertyName("Basic")]
|
||||
Basic,
|
||||
|
||||
[JsonPropertyName("LEVEL-UP")]
|
||||
LevelUp,
|
||||
|
||||
[JsonPropertyName("MEGA")]
|
||||
Mega,
|
||||
|
||||
[JsonPropertyName("RESTORED")]
|
||||
Restored,
|
||||
|
||||
[JsonPropertyName("Stage1")]
|
||||
Stage1,
|
||||
|
||||
[JsonPropertyName("Stage2")]
|
||||
Stage2,
|
||||
|
||||
[JsonPropertyName("V-UNION")]
|
||||
VUnion,
|
||||
|
||||
[JsonPropertyName("VMAX")]
|
||||
VMax,
|
||||
|
||||
[JsonPropertyName("VSTAR")]
|
||||
VStar
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Entities.Enums;
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum Variant
|
||||
{
|
||||
[JsonPropertyName("firstEdition")]
|
||||
FirstEdition,
|
||||
|
||||
[JsonPropertyName("holo")]
|
||||
Holo,
|
||||
|
||||
[JsonPropertyName("normal")]
|
||||
Normal,
|
||||
|
||||
[JsonPropertyName("reverse")]
|
||||
Reverse,
|
||||
|
||||
[JsonPropertyName("wPromo")]
|
||||
WPromo
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using OakArchive.Entities.Cards;
|
||||
using OakArchive.Entities.Enums;
|
||||
|
||||
namespace OakArchive.Entities.Grading;
|
||||
|
||||
public class Grading
|
||||
{
|
||||
[Key] public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[Required] public GradingCompany Company { get; set; } = GradingCompany.PSA;
|
||||
[Required] public string CertificateNumber { get; set; } = string.Empty;
|
||||
|
||||
public double Grade { get; set; }
|
||||
|
||||
public double? Centering { get; set; }
|
||||
public double? Corners { get; set; }
|
||||
public double? Edges { get; set; }
|
||||
public double? Surface { get; set; }
|
||||
|
||||
public string? GraderNotes { get; set; }
|
||||
|
||||
public DateTime GradedAt { get; set; }
|
||||
|
||||
[ForeignKey(nameof(CollectedCard))] public Guid CollectedCardId { get; set; }
|
||||
public virtual CollectedCard CollectedCard { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using OakArchive.Entities.Enums;
|
||||
using OakArchive.Entities.TCGdex;
|
||||
|
||||
namespace OakArchive.Entities.Serie;
|
||||
|
||||
public class Serie
|
||||
{
|
||||
[Key]
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[Required]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string? Logo { get; set; }
|
||||
|
||||
public Language? Language { get; set; }
|
||||
|
||||
//public DateTime? ReleaseDate { get; set; }
|
||||
|
||||
public virtual ICollection<Set.Set> Sets { get; set; } = new List<Set.Set>();
|
||||
|
||||
public virtual TcgDexSeriesInfo TcgDexSeriesInfo { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace OakArchive.Entities.Set;
|
||||
|
||||
public class CardCount
|
||||
{
|
||||
[Key] public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public int Total { get; set; } = 0;
|
||||
|
||||
public int Official { get; set; } = 0;
|
||||
|
||||
public int Normal { get; set; } = 0;
|
||||
|
||||
public int Reverse { get; set; } = 0;
|
||||
|
||||
public int Holo { get; set; } = 0;
|
||||
|
||||
public int FirstEd { get; set; } = 0;
|
||||
|
||||
[ForeignKey(nameof(Set))]
|
||||
public Guid SetId { get; set; }
|
||||
|
||||
public virtual Set Set { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using OakArchive.Entities.Cards;
|
||||
|
||||
namespace OakArchive.Entities.Set;
|
||||
|
||||
public class Legal
|
||||
{
|
||||
[Key] public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public bool Expanded { get; set; } = false;
|
||||
|
||||
public bool Standard { get; set; } = false;
|
||||
|
||||
[ForeignKey(nameof(Set))]
|
||||
public Guid? SetId { get; set; }
|
||||
public virtual Set? Set { get; set; }
|
||||
|
||||
[ForeignKey(nameof(Card))]
|
||||
public Guid? CardId { get; set; }
|
||||
public virtual Card? Card { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using OakArchive.Entities.CardMarket;
|
||||
using OakArchive.Entities.Cards;
|
||||
using OakArchive.Entities.Enums;
|
||||
using OakArchive.Entities.TCGdex;
|
||||
|
||||
namespace OakArchive.Entities.Set;
|
||||
|
||||
public class Set
|
||||
{
|
||||
[Key] public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[Required] public string Name { get; set; } = string.Empty;
|
||||
|
||||
public string? Symbol { get; set; }
|
||||
|
||||
public string? Logo { get; set; }
|
||||
|
||||
public Language Language { get; set; } = Language.En;
|
||||
|
||||
public DateTime? ReleaseDate { get; set; }
|
||||
|
||||
public ICollection<Card> Cards { get; set; } = new List<Card>();
|
||||
|
||||
public virtual TcgDexSetInfo SetInfo { get; set; } = null!;
|
||||
|
||||
public virtual CardMarketSetInfo CardMarketSetInfo { get; set; } = null!;
|
||||
|
||||
[ForeignKey(nameof(Serie))] public Guid SerieId { get; set; }
|
||||
public virtual Serie.Serie Serie { get; set; } = null!;
|
||||
|
||||
public virtual CardCount CardCount { get; set; } = null!;
|
||||
|
||||
public virtual Legal? Legal { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using OakArchive.Entities.Cards;
|
||||
|
||||
namespace OakArchive.Entities.TCGdex;
|
||||
|
||||
public class TcgDexCardInfo
|
||||
{
|
||||
[Key] public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[Required] public string FullId { get; set; } = string.Empty;
|
||||
|
||||
[Required] public int LocalId { get; set; } = 0;
|
||||
|
||||
[ForeignKey(nameof(Card))] public Guid CardId { get; set; }
|
||||
public virtual Card Card { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace OakArchive.Entities.TCGdex;
|
||||
|
||||
public class TcgDexSeriesInfo
|
||||
{
|
||||
[Key]
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[Required]
|
||||
public string SeriesId { get; set; } = string.Empty;
|
||||
|
||||
[ForeignKey(nameof(Set))]
|
||||
public Guid SeriesIdRef { get; set; }
|
||||
public virtual Serie.Serie Series { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace OakArchive.Entities.TCGdex;
|
||||
|
||||
public class TcgDexSetInfo
|
||||
{
|
||||
[Key]
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
[Required]
|
||||
public string SetId { get; set; } = string.Empty;
|
||||
|
||||
[ForeignKey(nameof(Set))]
|
||||
public Guid SetIdRef { get; set; }
|
||||
public virtual Set.Set Set { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace OakArchive.Entities.User;
|
||||
|
||||
public class ApplicationUser : IdentityUser<Guid>
|
||||
{
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
public virtual Settings Settings { get; set; } = new();
|
||||
|
||||
private Collection.Collection DefaultCollection { get; set; } = new();
|
||||
|
||||
public virtual ICollection<Collection.Collection> Collections { get; set; } = [];
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace OakArchive.Entities.User;
|
||||
|
||||
public class Settings
|
||||
{
|
||||
[Key]
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public bool AddCardsToDefaultList { get; set; } = true;
|
||||
|
||||
[ForeignKey(nameof(User))]
|
||||
public Guid UserId { get; set; }
|
||||
public virtual ApplicationUser User { get; set; } = null!;
|
||||
}
|
||||
+1002
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,743 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace OakArchive.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Init : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetRoles",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
NormalizedName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Collections",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Description = table.Column<string>(type: "text", nullable: true),
|
||||
CreatedBy = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
InviteCode = table.Column<string>(type: "text", nullable: false),
|
||||
IsPublic = table.Column<bool>(type: "boolean", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Collections", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Series",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Logo = table.Column<string>(type: "text", nullable: true),
|
||||
Language = table.Column<int>(type: "integer", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Series", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetRoleClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
RoleId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ClaimType = table.Column<string>(type: "text", nullable: true),
|
||||
ClaimValue = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalTable: "AspNetRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUsers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
DefaultCollectionId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
UserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
NormalizedUserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
Email = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
NormalizedEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false),
|
||||
PasswordHash = table.Column<string>(type: "text", nullable: true),
|
||||
SecurityStamp = table.Column<string>(type: "text", nullable: true),
|
||||
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true),
|
||||
PhoneNumber = table.Column<string>(type: "text", nullable: true),
|
||||
PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false),
|
||||
TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
LockoutEnd = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
||||
LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
AccessFailedCount = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUsers_Collections_DefaultCollectionId",
|
||||
column: x => x.DefaultCollectionId,
|
||||
principalTable: "Collections",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Sets",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Symbol = table.Column<string>(type: "text", nullable: true),
|
||||
Logo = table.Column<string>(type: "text", nullable: true),
|
||||
Language = table.Column<int>(type: "integer", nullable: false),
|
||||
ReleaseDate = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
SerieId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Sets", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Sets_Series_SerieId",
|
||||
column: x => x.SerieId,
|
||||
principalTable: "Series",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TcgDexSeriesInfos",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
SeriesId = table.Column<string>(type: "text", nullable: false),
|
||||
SeriesIdRef = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TcgDexSeriesInfos", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TcgDexSeriesInfos_Series_SeriesIdRef",
|
||||
column: x => x.SeriesIdRef,
|
||||
principalTable: "Series",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserClaims",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ClaimType = table.Column<string>(type: "text", nullable: true),
|
||||
ClaimValue = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserLogins",
|
||||
columns: table => new
|
||||
{
|
||||
LoginProvider = table.Column<string>(type: "text", nullable: false),
|
||||
ProviderKey = table.Column<string>(type: "text", nullable: false),
|
||||
ProviderDisplayName = table.Column<string>(type: "text", nullable: true),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserRoles",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
RoleId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalTable: "AspNetRoles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AspNetUserTokens",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
LoginProvider = table.Column<string>(type: "text", nullable: false),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Value = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
|
||||
table.ForeignKey(
|
||||
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Settings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
AddCardsToDefaultList = table.Column<bool>(type: "boolean", nullable: false),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Settings", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Settings_AspNetUsers_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserCollections",
|
||||
columns: table => new
|
||||
{
|
||||
CollectionsId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
MembersId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserCollections", x => new { x.CollectionsId, x.MembersId });
|
||||
table.ForeignKey(
|
||||
name: "FK_UserCollections_AspNetUsers_MembersId",
|
||||
column: x => x.MembersId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserCollections_Collections_CollectionsId",
|
||||
column: x => x.CollectionsId,
|
||||
principalTable: "Collections",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "CardCounts",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Total = table.Column<int>(type: "integer", nullable: false),
|
||||
Official = table.Column<int>(type: "integer", nullable: false),
|
||||
Normal = table.Column<int>(type: "integer", nullable: false),
|
||||
Reverse = table.Column<int>(type: "integer", nullable: false),
|
||||
Holo = table.Column<int>(type: "integer", nullable: false),
|
||||
FirstEd = table.Column<int>(type: "integer", nullable: false),
|
||||
SetId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CardCounts", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_CardCounts_Sets_SetId",
|
||||
column: x => x.SetId,
|
||||
principalTable: "Sets",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "CardMarketSetInfos",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
ExpansionId = table.Column<string>(type: "text", nullable: false),
|
||||
SetId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CardMarketSetInfos", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_CardMarketSetInfos_Sets_SetId",
|
||||
column: x => x.SetId,
|
||||
principalTable: "Sets",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Cards",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Image = table.Column<string>(type: "text", nullable: false),
|
||||
CardNumber = table.Column<int>(type: "integer", nullable: false),
|
||||
PHash = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
|
||||
Hp = table.Column<int>(type: "integer", nullable: true),
|
||||
Retreat = table.Column<int>(type: "integer", nullable: true),
|
||||
TrainerType = table.Column<string>(type: "text", nullable: true),
|
||||
EnergyType = table.Column<string>(type: "text", nullable: true),
|
||||
Illustrator = table.Column<string>(type: "text", nullable: true),
|
||||
EvolveFrom = table.Column<string>(type: "text", nullable: true),
|
||||
Description = table.Column<string>(type: "text", nullable: true),
|
||||
RegulationMark = table.Column<string>(type: "text", nullable: true),
|
||||
Rarity = table.Column<int>(type: "integer", nullable: true),
|
||||
Category = table.Column<int>(type: "integer", nullable: true),
|
||||
Variants = table.Column<string>(type: "jsonb", nullable: true),
|
||||
Types = table.Column<string>(type: "jsonb", nullable: true),
|
||||
SetId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Cards", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Cards_Sets_SetId",
|
||||
column: x => x.SetId,
|
||||
principalTable: "Sets",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TcgDexSetInfos",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
SetId = table.Column<string>(type: "text", nullable: false),
|
||||
SetIdRef = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TcgDexSetInfos", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TcgDexSetInfos_Sets_SetIdRef",
|
||||
column: x => x.SetIdRef,
|
||||
principalTable: "Sets",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Attacks",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Cost = table.Column<string>(type: "jsonb", nullable: false),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Damage = table.Column<int>(type: "integer", nullable: true),
|
||||
Effect = table.Column<string>(type: "text", nullable: false),
|
||||
CardId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Attacks", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Attacks_Cards_CardId",
|
||||
column: x => x.CardId,
|
||||
principalTable: "Cards",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "CollectedCards",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Variant = table.Column<int>(type: "integer", nullable: false),
|
||||
Condition = table.Column<int>(type: "integer", nullable: false),
|
||||
Count = table.Column<int>(type: "integer", nullable: false),
|
||||
Language = table.Column<int>(type: "integer", nullable: false),
|
||||
ScannedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
ScannedById = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CollectionId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
CardId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CollectedCards", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_CollectedCards_AspNetUsers_ScannedById",
|
||||
column: x => x.ScannedById,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_CollectedCards_Cards_CardId",
|
||||
column: x => x.CardId,
|
||||
principalTable: "Cards",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_CollectedCards_Collections_CollectionId",
|
||||
column: x => x.CollectionId,
|
||||
principalTable: "Collections",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Legals",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Expanded = table.Column<bool>(type: "boolean", nullable: false),
|
||||
Standard = table.Column<bool>(type: "boolean", nullable: false),
|
||||
SetId = table.Column<Guid>(type: "uuid", nullable: true),
|
||||
CardId = table.Column<Guid>(type: "uuid", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Legals", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Legals_Cards_CardId",
|
||||
column: x => x.CardId,
|
||||
principalTable: "Cards",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Legals_Sets_SetId",
|
||||
column: x => x.SetId,
|
||||
principalTable: "Sets",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TcgDexCardInfos",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
FullId = table.Column<string>(type: "text", nullable: false),
|
||||
LocalId = table.Column<int>(type: "integer", nullable: false),
|
||||
CardId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TcgDexCardInfos", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_TcgDexCardInfos_Cards_CardId",
|
||||
column: x => x.CardId,
|
||||
principalTable: "Cards",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Weaknesses",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Type = table.Column<string>(type: "text", nullable: false),
|
||||
Value = table.Column<string>(type: "text", nullable: false),
|
||||
CardId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Weaknesses", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Weaknesses_Cards_CardId",
|
||||
column: x => x.CardId,
|
||||
principalTable: "Cards",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Gradings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Company = table.Column<int>(type: "integer", nullable: false),
|
||||
CertificateNumber = table.Column<string>(type: "text", nullable: false),
|
||||
Grade = table.Column<double>(type: "double precision", nullable: false),
|
||||
Centering = table.Column<double>(type: "double precision", nullable: true),
|
||||
Corners = table.Column<double>(type: "double precision", nullable: true),
|
||||
Edges = table.Column<double>(type: "double precision", nullable: true),
|
||||
Surface = table.Column<double>(type: "double precision", nullable: true),
|
||||
GraderNotes = table.Column<string>(type: "text", nullable: true),
|
||||
GradedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
CollectedCardId = table.Column<Guid>(type: "uuid", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Gradings", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Gradings_CollectedCards_CollectedCardId",
|
||||
column: x => x.CollectedCardId,
|
||||
principalTable: "CollectedCards",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetRoleClaims_RoleId",
|
||||
table: "AspNetRoleClaims",
|
||||
column: "RoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "RoleNameIndex",
|
||||
table: "AspNetRoles",
|
||||
column: "NormalizedName",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserClaims_UserId",
|
||||
table: "AspNetUserClaims",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserLogins_UserId",
|
||||
table: "AspNetUserLogins",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUserRoles_RoleId",
|
||||
table: "AspNetUserRoles",
|
||||
column: "RoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "EmailIndex",
|
||||
table: "AspNetUsers",
|
||||
column: "NormalizedEmail");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AspNetUsers_DefaultCollectionId",
|
||||
table: "AspNetUsers",
|
||||
column: "DefaultCollectionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "UserNameIndex",
|
||||
table: "AspNetUsers",
|
||||
column: "NormalizedUserName",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Attacks_CardId",
|
||||
table: "Attacks",
|
||||
column: "CardId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CardCounts_SetId",
|
||||
table: "CardCounts",
|
||||
column: "SetId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CardMarketSetInfos_SetId",
|
||||
table: "CardMarketSetInfos",
|
||||
column: "SetId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Cards_SetId",
|
||||
table: "Cards",
|
||||
column: "SetId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CollectedCards_CardId",
|
||||
table: "CollectedCards",
|
||||
column: "CardId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CollectedCards_CollectionId",
|
||||
table: "CollectedCards",
|
||||
column: "CollectionId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_CollectedCards_ScannedById",
|
||||
table: "CollectedCards",
|
||||
column: "ScannedById");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Gradings_CollectedCardId",
|
||||
table: "Gradings",
|
||||
column: "CollectedCardId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Legals_CardId",
|
||||
table: "Legals",
|
||||
column: "CardId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Legals_SetId",
|
||||
table: "Legals",
|
||||
column: "SetId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Sets_SerieId",
|
||||
table: "Sets",
|
||||
column: "SerieId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Settings_UserId",
|
||||
table: "Settings",
|
||||
column: "UserId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TcgDexCardInfos_CardId",
|
||||
table: "TcgDexCardInfos",
|
||||
column: "CardId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TcgDexSeriesInfos_SeriesIdRef",
|
||||
table: "TcgDexSeriesInfos",
|
||||
column: "SeriesIdRef",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TcgDexSetInfos_SetIdRef",
|
||||
table: "TcgDexSetInfos",
|
||||
column: "SetIdRef",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserCollections_MembersId",
|
||||
table: "UserCollections",
|
||||
column: "MembersId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Weaknesses_CardId",
|
||||
table: "Weaknesses",
|
||||
column: "CardId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetRoleClaims");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserClaims");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserLogins");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserRoles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUserTokens");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Attacks");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "CardCounts");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "CardMarketSetInfos");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Gradings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Legals");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Settings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TcgDexCardInfos");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TcgDexSeriesInfos");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "TcgDexSetInfos");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserCollections");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Weaknesses");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetRoles");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "CollectedCards");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AspNetUsers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Cards");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Collections");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Sets");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Series");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,999 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using OakArchive.Database;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace OakArchive.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "10.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("ApplicationUserCollection", b =>
|
||||
{
|
||||
b.Property<Guid>("CollectionsId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("MembersId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("CollectionsId", "MembersId");
|
||||
|
||||
b.HasIndex("MembersId");
|
||||
|
||||
b.ToTable("UserCollections", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole<System.Guid>", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("RoleId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
||||
{
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("RoleId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
||||
{
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.CardMarket.CardMarketSetInfo", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("ExpansionId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("SetId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SetId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("CardMarketSetInfos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Cards.Attack", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("CardId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.PrimitiveCollection<string>("Cost")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb");
|
||||
|
||||
b.Property<int?>("Damage")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Effect")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CardId");
|
||||
|
||||
b.ToTable("Attacks");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Cards.Card", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("CardNumber")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int?>("Category")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("EnergyType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("EvolveFrom")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("Hp")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Illustrator")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Image")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<decimal>("PHash")
|
||||
.HasColumnType("numeric(20,0)");
|
||||
|
||||
b.Property<int?>("Rarity")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("RegulationMark")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("Retreat")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("SetId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("TrainerType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.PrimitiveCollection<string>("Types")
|
||||
.HasColumnType("jsonb");
|
||||
|
||||
b.PrimitiveCollection<string>("Variants")
|
||||
.HasColumnType("jsonb");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SetId");
|
||||
|
||||
b.ToTable("Cards");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Cards.CollectedCard", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("CardId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("CollectionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Condition")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Language")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTime>("ScannedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("ScannedById")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Variant")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CardId");
|
||||
|
||||
b.HasIndex("CollectionId");
|
||||
|
||||
b.HasIndex("ScannedById");
|
||||
|
||||
b.ToTable("CollectedCards");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Cards.Weakness", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("CardId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CardId");
|
||||
|
||||
b.ToTable("Weaknesses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Collection.Collection", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("CreatedBy")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("InviteCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsPublic")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Collections");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Grading.Grading", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<double?>("Centering")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<string>("CertificateNumber")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("CollectedCardId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Company")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<double?>("Corners")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<double?>("Edges")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<double>("Grade")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.Property<DateTime>("GradedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("GraderNotes")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<double?>("Surface")
|
||||
.HasColumnType("double precision");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CollectedCardId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Gradings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Serie.Serie", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int?>("Language")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Logo")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Series");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Set.CardCount", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("FirstEd")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Holo")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Normal")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Official")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<int>("Reverse")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid>("SetId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Total")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SetId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("CardCounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Set.Legal", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("CardId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("Expanded")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid?>("SetId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("Standard")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CardId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("SetId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Legals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Set.Set", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("Language")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Logo")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime?>("ReleaseDate")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("SerieId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SerieId");
|
||||
|
||||
b.ToTable("Sets");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.TCGdex.TcgDexCardInfo", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("CardId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("FullId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("LocalId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CardId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("TcgDexCardInfos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.TCGdex.TcgDexSeriesInfo", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("SeriesId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("SeriesIdRef")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SeriesIdRef")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("TcgDexSeriesInfos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.TCGdex.TcgDexSetInfo", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("SetId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("SetIdRef")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SetIdRef")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("TcgDexSetInfos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.User.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("DefaultCollectionId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("DefaultCollectionId");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.User.Settings", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("AddCardsToDefaultList")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Settings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ApplicationUserCollection", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Collection.Collection", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("CollectionsId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("OakArchive.Entities.User.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("MembersId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole<System.Guid>", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.User.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.User.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole<System.Guid>", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("OakArchive.Entities.User.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.User.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.CardMarket.CardMarketSetInfo", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Set.Set", "Set")
|
||||
.WithOne("CardMarketSetInfo")
|
||||
.HasForeignKey("OakArchive.Entities.CardMarket.CardMarketSetInfo", "SetId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Set");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Cards.Attack", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Cards.Card", "Card")
|
||||
.WithMany("Attacks")
|
||||
.HasForeignKey("CardId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Card");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Cards.Card", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Set.Set", "Set")
|
||||
.WithMany("Cards")
|
||||
.HasForeignKey("SetId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Set");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Cards.CollectedCard", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Cards.Card", "Card")
|
||||
.WithMany()
|
||||
.HasForeignKey("CardId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("OakArchive.Entities.Collection.Collection", "Collection")
|
||||
.WithMany("Cards")
|
||||
.HasForeignKey("CollectionId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("OakArchive.Entities.User.ApplicationUser", "ScannedBy")
|
||||
.WithMany()
|
||||
.HasForeignKey("ScannedById")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Card");
|
||||
|
||||
b.Navigation("Collection");
|
||||
|
||||
b.Navigation("ScannedBy");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Cards.Weakness", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Cards.Card", "Card")
|
||||
.WithMany("Weaknesses")
|
||||
.HasForeignKey("CardId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Card");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Grading.Grading", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Cards.CollectedCard", "CollectedCard")
|
||||
.WithOne("Grading")
|
||||
.HasForeignKey("OakArchive.Entities.Grading.Grading", "CollectedCardId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CollectedCard");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Set.CardCount", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Set.Set", "Set")
|
||||
.WithOne("CardCount")
|
||||
.HasForeignKey("OakArchive.Entities.Set.CardCount", "SetId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Set");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Set.Legal", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Cards.Card", "Card")
|
||||
.WithOne("Legal")
|
||||
.HasForeignKey("OakArchive.Entities.Set.Legal", "CardId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("OakArchive.Entities.Set.Set", "Set")
|
||||
.WithOne("Legal")
|
||||
.HasForeignKey("OakArchive.Entities.Set.Legal", "SetId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.Navigation("Card");
|
||||
|
||||
b.Navigation("Set");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Set.Set", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Serie.Serie", "Serie")
|
||||
.WithMany("Sets")
|
||||
.HasForeignKey("SerieId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Serie");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.TCGdex.TcgDexCardInfo", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Cards.Card", "Card")
|
||||
.WithOne("TcgDexCardInfo")
|
||||
.HasForeignKey("OakArchive.Entities.TCGdex.TcgDexCardInfo", "CardId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Card");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.TCGdex.TcgDexSeriesInfo", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Serie.Serie", "Series")
|
||||
.WithOne("TcgDexSeriesInfo")
|
||||
.HasForeignKey("OakArchive.Entities.TCGdex.TcgDexSeriesInfo", "SeriesIdRef")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Series");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.TCGdex.TcgDexSetInfo", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Set.Set", "Set")
|
||||
.WithOne("SetInfo")
|
||||
.HasForeignKey("OakArchive.Entities.TCGdex.TcgDexSetInfo", "SetIdRef")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Set");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.User.ApplicationUser", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.Collection.Collection", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("DefaultCollectionId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.User.Settings", b =>
|
||||
{
|
||||
b.HasOne("OakArchive.Entities.User.ApplicationUser", "User")
|
||||
.WithOne("Settings")
|
||||
.HasForeignKey("OakArchive.Entities.User.Settings", "UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Cards.Card", b =>
|
||||
{
|
||||
b.Navigation("Attacks");
|
||||
|
||||
b.Navigation("Legal");
|
||||
|
||||
b.Navigation("TcgDexCardInfo")
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Weaknesses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Cards.CollectedCard", b =>
|
||||
{
|
||||
b.Navigation("Grading");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Collection.Collection", b =>
|
||||
{
|
||||
b.Navigation("Cards");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Serie.Serie", b =>
|
||||
{
|
||||
b.Navigation("Sets");
|
||||
|
||||
b.Navigation("TcgDexSeriesInfo")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.Set.Set", b =>
|
||||
{
|
||||
b.Navigation("CardCount")
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CardMarketSetInfo")
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Cards");
|
||||
|
||||
b.Navigation("Legal");
|
||||
|
||||
b.Navigation("SetInfo")
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("OakArchive.Entities.User.ApplicationUser", b =>
|
||||
{
|
||||
b.Navigation("Settings")
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Models.TcgDex;
|
||||
|
||||
public class Attack
|
||||
{
|
||||
[JsonPropertyName("cost")]
|
||||
public List<string>? Cost { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("effect")]
|
||||
public string? Effect { get; set; }
|
||||
|
||||
[JsonPropertyName("damage")]
|
||||
public int? Damage { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using OakArchive.Entities.Set;
|
||||
|
||||
namespace OakArchive.Models.TcgDex;
|
||||
|
||||
public class Card
|
||||
{
|
||||
[JsonPropertyName("category")]
|
||||
public string? Category { get; set; }
|
||||
|
||||
[JsonPropertyName("id")]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[JsonPropertyName("illustrator")]
|
||||
public string? Illustrator { get; set; }
|
||||
|
||||
[JsonPropertyName("image")]
|
||||
public string? Image { get; set; }
|
||||
|
||||
[JsonPropertyName("localId")]
|
||||
public int? LocalId { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("rarity")]
|
||||
public string? Rarity { get; set; }
|
||||
|
||||
[JsonPropertyName("set")]
|
||||
public Entities.Set.Set? Set { get; set; }
|
||||
|
||||
[JsonPropertyName("variants")]
|
||||
public Variants? Variants { get; set; }
|
||||
|
||||
[JsonPropertyName("hp")]
|
||||
public int? Hp { get; set; }
|
||||
|
||||
[JsonPropertyName("types")]
|
||||
public List<string>? Types { get; set; }
|
||||
|
||||
[JsonPropertyName("evolveFrom")]
|
||||
public string? EvolveFrom { get; set; }
|
||||
|
||||
[JsonPropertyName("description")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[JsonPropertyName("stage")]
|
||||
public string? Stage { get; set; }
|
||||
|
||||
[JsonPropertyName("attacks")]
|
||||
public List<Attack>? Attacks { get; set; }
|
||||
|
||||
[JsonPropertyName("weaknesses")]
|
||||
public List<Weakness>? Weaknesses { get; set; }
|
||||
|
||||
[JsonPropertyName("retreat")]
|
||||
public int? Retreat { get; set; }
|
||||
|
||||
[JsonPropertyName("regulationMark")]
|
||||
public string? RegulationMark { get; set; }
|
||||
|
||||
[JsonPropertyName("legal")]
|
||||
public Legal? Legal { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Models.TcgDex;
|
||||
|
||||
public class CardCount
|
||||
{
|
||||
[JsonPropertyName("firstEd")]
|
||||
public int? FirstEd { get; set; }
|
||||
|
||||
[JsonPropertyName("holo")]
|
||||
public int? Holo { get; set; }
|
||||
|
||||
[JsonPropertyName("normal")]
|
||||
public int? Normal { get; set; }
|
||||
|
||||
[JsonPropertyName("official")]
|
||||
public int? Official { get; set; }
|
||||
|
||||
[JsonPropertyName("reverse")]
|
||||
public int? Reverse { get; set; }
|
||||
|
||||
[JsonPropertyName("total")]
|
||||
public int? Total { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Models.TcgDex;
|
||||
|
||||
public class Legal
|
||||
{
|
||||
[JsonPropertyName("standard")]
|
||||
public bool? Standard { get; set; }
|
||||
|
||||
[JsonPropertyName("expanded")]
|
||||
public bool? Expanded { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Models.TcgDex;
|
||||
|
||||
public class Serie
|
||||
{
|
||||
[JsonPropertyName("id")]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[JsonPropertyName("logo")]
|
||||
public string? Logo { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("sets")]
|
||||
public List<SetBrief>? Sets { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Models.TcgDex;
|
||||
|
||||
public class SerieBrief
|
||||
{
|
||||
[JsonPropertyName("id")]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("logo")]
|
||||
public string? Logo { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Models.TcgDex;
|
||||
|
||||
public class Set
|
||||
{
|
||||
[JsonPropertyName("cardCount")]
|
||||
public CardCount CardCount { get; set; }
|
||||
|
||||
[JsonPropertyName("cards")]
|
||||
public List<Card> Cards { get; set; }
|
||||
|
||||
[JsonPropertyName("id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonPropertyName("legal")]
|
||||
public Legal Legal { get; set; }
|
||||
|
||||
[JsonPropertyName("logo")]
|
||||
public string Logo { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonPropertyName("releaseDate")]
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
|
||||
[JsonPropertyName("serie")]
|
||||
public Serie Serie { get; set; }
|
||||
|
||||
[JsonPropertyName("symbol")]
|
||||
public string Symbol { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Models.TcgDex;
|
||||
|
||||
public class SetBrief
|
||||
{
|
||||
[JsonPropertyName("cardCount")]
|
||||
public CardCount? CardCount { get; set; }
|
||||
|
||||
[JsonPropertyName("id")]
|
||||
public string? Id { get; set; }
|
||||
|
||||
[JsonPropertyName("logo")]
|
||||
public string? Logo { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("symbol")]
|
||||
public string? Symbol { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Models.TcgDex;
|
||||
|
||||
public class Variants
|
||||
{
|
||||
[JsonPropertyName("firstEdition")]
|
||||
public bool? FirstEdition { get; set; }
|
||||
|
||||
[JsonPropertyName("holo")]
|
||||
public bool? Holo { get; set; }
|
||||
|
||||
[JsonPropertyName("normal")]
|
||||
public bool? Normal { get; set; }
|
||||
|
||||
[JsonPropertyName("reverse")]
|
||||
public bool? Reverse { get; set; }
|
||||
|
||||
[JsonPropertyName("wPromo")]
|
||||
public bool? WPromo { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OakArchive.Models.TcgDex;
|
||||
|
||||
public class Weakness
|
||||
{
|
||||
[JsonPropertyName("type")]
|
||||
public string? Type { get; set; }
|
||||
|
||||
[JsonPropertyName("value")]
|
||||
public string? Value { get; set; }
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CoenM.ImageSharp.ImageHash" Version="1.3.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
|
||||
@@ -28,13 +29,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Controllers\" />
|
||||
<Folder Include="Entities\CardMarket\" />
|
||||
<Folder Include="Entities\Cards\" />
|
||||
<Folder Include="Entities\Collection\" />
|
||||
<Folder Include="Entities\TCGdex\" />
|
||||
<Folder Include="Entities\User\" />
|
||||
<Folder Include="Models\" />
|
||||
<Folder Include="Controllers\V1\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
+49
-3
@@ -1,21 +1,67 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OakArchive.Database;
|
||||
using OakArchive.Services;
|
||||
|
||||
namespace OakArchive;
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
|
||||
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||
options.UseNpgsql(builder.Configuration["DefaultConnection"]));
|
||||
|
||||
|
||||
builder.Services.AddMemoryCache(); // Registriert das native IMemoryCache von Microsoft
|
||||
builder.Services.AddSingleton<IMemoryCacheService, MemoryCacheService>();
|
||||
|
||||
builder.Services.AddHttpClient<ITcgDexService, TcgDexService>(client =>
|
||||
{
|
||||
client.BaseAddress = new Uri("https://api.tcgdex.net/v2/");
|
||||
client.DefaultRequestHeaders.Add("Accept", "application/json");
|
||||
});
|
||||
|
||||
builder.Services.AddScoped<ITcgDexDataUpdater, TcgDexDataUpdater>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
app.Lifetime.ApplicationStarted.Register(async () =>
|
||||
{
|
||||
// Da ApplicationStarted synchron registriert, machen wir hier einen neuen asynchronen Scope auf
|
||||
using var scope = app.Services.CreateScope();
|
||||
try
|
||||
{
|
||||
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
|
||||
Console.WriteLine("[INFO] Prüfe auf ausstehende Datenbank-Migrationen...");
|
||||
|
||||
// Führt alle ausstehenden Migrationen auf der PostgreSQL-Datenbank aus.
|
||||
// Falls die Datenbank noch gar nicht existiert, wird sie hier automatisch erstellt!
|
||||
await context.Database.MigrateAsync();
|
||||
|
||||
var updater = scope.ServiceProvider.GetRequiredService<ITcgDexDataUpdater>();
|
||||
|
||||
Console.WriteLine("[INFO] === Starte TCGdex Test-Sync im Hintergrund ===");
|
||||
|
||||
var result = await updater.SyncBaseDataFromTcgDex();
|
||||
|
||||
Console.WriteLine($"[INFO] === Test-Sync beendet! Neue Daten geladen: {result} ===");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[FEHLER] !!! Fehler beim Test-Sync: {ex.Message} !!!");
|
||||
Console.WriteLine(ex.StackTrace);
|
||||
}
|
||||
});
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace OakArchive.Services;
|
||||
|
||||
public interface IMemoryCacheService
|
||||
{
|
||||
Task<T?> GetOrCreateAsync<T>(string cacheKey, Func<Task<T?>> createItem, TimeSpan? expiration = null)
|
||||
where T : class;
|
||||
|
||||
void Remove(string cacheKey);
|
||||
}
|
||||
|
||||
public class MemoryCacheService : IMemoryCacheService
|
||||
{
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
private readonly TimeSpan _defaultExpiration = TimeSpan.FromHours(1);
|
||||
|
||||
public MemoryCacheService(IMemoryCache memoryCache)
|
||||
{
|
||||
_memoryCache = memoryCache;
|
||||
}
|
||||
|
||||
public async Task<T?> GetOrCreateAsync<T>(string cacheKey, Func<Task<T?>> createItem, TimeSpan? expiration = null)
|
||||
where T : class
|
||||
{
|
||||
if (_memoryCache.TryGetValue(cacheKey, out T? cachedItem))
|
||||
{
|
||||
return cachedItem;
|
||||
}
|
||||
|
||||
var item = await createItem();
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var cacheOptions = new MemoryCacheEntryOptions()
|
||||
.SetAbsoluteExpiration(expiration ?? _defaultExpiration);
|
||||
|
||||
_memoryCache.Set(cacheKey, item, cacheOptions);
|
||||
|
||||
return item!;
|
||||
}
|
||||
|
||||
public void Remove(string cacheKey)
|
||||
{
|
||||
_memoryCache.Remove(cacheKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OakArchive.Database;
|
||||
using OakArchive.Entities.CardMarket;
|
||||
using OakArchive.Entities.Cards;
|
||||
using OakArchive.Entities.Enums;
|
||||
using OakArchive.Entities.TCGdex;
|
||||
using OakArchive.Util;
|
||||
using OakArchive.Util.Extensions;
|
||||
using Card = OakArchive.Entities.Cards.Card;
|
||||
using CardCount = OakArchive.Entities.Set.CardCount;
|
||||
using Legal = OakArchive.Entities.Set.Legal;
|
||||
using Set = OakArchive.Entities.Set.Set;
|
||||
|
||||
namespace OakArchive.Services;
|
||||
|
||||
public interface ITcgDexDataUpdater
|
||||
{
|
||||
public Task<bool> SyncBaseDataFromTcgDex();
|
||||
|
||||
public Task<Card>
|
||||
UpdateCard(string set, int id, string language);
|
||||
}
|
||||
|
||||
public class TcgDexDataUpdater : ITcgDexDataUpdater
|
||||
{
|
||||
private readonly ITcgDexService _tcgDexService;
|
||||
private readonly ApplicationDbContext _dbContext;
|
||||
|
||||
private readonly List<Language> _languages = Enum.GetValues<Language>().ToList();
|
||||
|
||||
public TcgDexDataUpdater(ITcgDexService tcgDexService, ApplicationDbContext dbContext)
|
||||
{
|
||||
_tcgDexService = tcgDexService;
|
||||
_dbContext = dbContext;
|
||||
}
|
||||
|
||||
public async Task<bool> SyncBaseDataFromTcgDex()
|
||||
{
|
||||
var hasChanges = false;
|
||||
int i = 0;
|
||||
foreach (var language in _languages)
|
||||
{
|
||||
var apiSeriesBriefs = await _tcgDexService.GetSeries(language.ToApiCode());
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
foreach (var serieBrief in apiSeriesBriefs)
|
||||
{
|
||||
if (i == 1) return true;
|
||||
i += 1;
|
||||
if (string.IsNullOrEmpty(serieBrief.Id)) continue;
|
||||
|
||||
var dbSerie = await EnsureSerieExistsAsync(serieBrief, language);
|
||||
|
||||
var fullApiSerie = await _tcgDexService.GetSetsOfSeries(serieBrief.Id, language.ToApiCode());
|
||||
if (fullApiSerie?.Sets == null) continue;
|
||||
|
||||
await Task.Delay(300);
|
||||
|
||||
foreach (var setBrief in fullApiSerie.Sets)
|
||||
{
|
||||
if (string.IsNullOrEmpty(setBrief.Id)) continue;
|
||||
|
||||
var isSetInDb = dbSerie.Sets.Any(s => s.SetInfo?.SetId == setBrief.Id);
|
||||
if (isSetInDb) continue;
|
||||
|
||||
var fullApiSet = await _tcgDexService.GetSet(setBrief.Id, language.ToApiCode());
|
||||
if (fullApiSet == null) continue;
|
||||
|
||||
var dbSet = await BuildSetEntityWithCardsAsync(setBrief, fullApiSet, language);
|
||||
|
||||
dbSerie.Sets.Add(dbSet);
|
||||
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
if (await _dbContext.SaveChangesAsync() > 0)
|
||||
{
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
public async Task<Card> UpdateCard(string set, int id, string language)
|
||||
{
|
||||
var tcgDexCardId = $"{set.ToLower()}-{id}";
|
||||
if (!Enum.TryParse<Language>(language, true, out var langEnum))
|
||||
{
|
||||
langEnum = Language.En;
|
||||
}
|
||||
|
||||
var dbCard = await _dbContext.Cards
|
||||
.Include(c => c.TcgDexCardInfo)
|
||||
.Include(c => c.Attacks)
|
||||
.Include(c => c.Weaknesses)
|
||||
.FirstOrDefaultAsync(c => c.TcgDexCardInfo.FullId == tcgDexCardId && c.Set.Language == langEnum);
|
||||
|
||||
if (dbCard == null)
|
||||
{
|
||||
throw new KeyNotFoundException(
|
||||
$"Die Basis-Karte mit der TCGdex-ID '{tcgDexCardId}' wurde für die Sprache '{language}' nicht in der Datenbank gefunden. Führe zuerst den Basis-Sync aus.");
|
||||
}
|
||||
|
||||
var apiCard = await _tcgDexService.GetCard(set, id, language);
|
||||
if (apiCard == null)
|
||||
{
|
||||
throw new HttpRequestException(
|
||||
$"Die Karte '{tcgDexCardId}' konnte von der TCGdex-API nicht geladen werden.");
|
||||
}
|
||||
|
||||
dbCard.Name = apiCard.Name ?? dbCard.Name;
|
||||
dbCard.Hp = apiCard.Hp;
|
||||
dbCard.Retreat = apiCard.Retreat;
|
||||
dbCard.Illustrator = apiCard.Illustrator;
|
||||
dbCard.EvolveFrom = apiCard.EvolveFrom;
|
||||
dbCard.Description = apiCard.Description;
|
||||
dbCard.RegulationMark = apiCard.RegulationMark;
|
||||
dbCard.Types = apiCard.Types;
|
||||
|
||||
if (!string.IsNullOrEmpty(apiCard.Rarity) &&
|
||||
Enum.TryParse<Rarity>(apiCard.Rarity.Replace(" ", ""), true, out var parsedRarity))
|
||||
{
|
||||
dbCard.Rarity = parsedRarity;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(apiCard.Category) &&
|
||||
Enum.TryParse<Category>(apiCard.Category, true, out var parsedCategory))
|
||||
{
|
||||
dbCard.Category = parsedCategory;
|
||||
}
|
||||
|
||||
dbCard.Variants = MapApiVariantsToEnumList(apiCard.Variants);
|
||||
|
||||
dbCard.Attacks.Clear();
|
||||
if (apiCard.Attacks != null)
|
||||
{
|
||||
foreach (var apiAttack in apiCard.Attacks)
|
||||
{
|
||||
dbCard.Attacks.Add(new Attack
|
||||
{
|
||||
Name = apiAttack.Name ?? "Unknown",
|
||||
Damage = apiAttack.Damage,
|
||||
Effect = apiAttack.Effect ?? string.Empty,
|
||||
Cost = apiAttack.Cost ?? []
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
dbCard.Weaknesses.Clear();
|
||||
if (apiCard.Weaknesses != null)
|
||||
{
|
||||
foreach (var apiWeakness in apiCard.Weaknesses)
|
||||
{
|
||||
dbCard.Weaknesses.Add(new Weakness
|
||||
{
|
||||
Type = apiWeakness.Type ?? "Unknown",
|
||||
Value = apiWeakness.Value ?? string.Empty
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return dbCard;
|
||||
}
|
||||
|
||||
private List<Variant> MapApiVariantsToEnumList(Models.TcgDex.Variants? apiVariants)
|
||||
{
|
||||
var list = new List<Variant>();
|
||||
if (apiVariants == null) return list;
|
||||
|
||||
if (apiVariants.FirstEdition == true) list.Add(Variant.FirstEdition);
|
||||
if (apiVariants.Holo == true) list.Add(Variant.Holo);
|
||||
if (apiVariants.Normal == true) list.Add(Variant.Normal);
|
||||
if (apiVariants.Reverse == true) list.Add(Variant.Reverse);
|
||||
if (apiVariants.WPromo == true) list.Add(Variant.WPromo);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private async Task<Entities.Serie.Serie> EnsureSerieExistsAsync(Models.TcgDex.SerieBrief brief, Language language)
|
||||
{
|
||||
var dbSerie = await _dbContext.Series
|
||||
.Include(s => s.Sets)
|
||||
.ThenInclude(s => s.SetInfo)
|
||||
.FirstOrDefaultAsync(s => s.TcgDexSeriesInfo.SeriesId == brief.Id && s.Language == language);
|
||||
|
||||
if (dbSerie != null) return dbSerie;
|
||||
|
||||
dbSerie = new Entities.Serie.Serie
|
||||
{
|
||||
Language = language,
|
||||
Name = brief.Name ?? "Unknown",
|
||||
Logo = brief.Logo,
|
||||
TcgDexSeriesInfo = new TcgDexSeriesInfo { SeriesId = brief.Id! }
|
||||
};
|
||||
_dbContext.Series.Add(dbSerie);
|
||||
|
||||
return dbSerie;
|
||||
}
|
||||
|
||||
private async Task<Set> BuildSetEntityWithCardsAsync(Models.TcgDex.SetBrief setBrief, Models.TcgDex.Set fullApiSet,
|
||||
Language language)
|
||||
{
|
||||
DateTime? utcReleaseDate = fullApiSet.ReleaseDate != null
|
||||
? DateTime.SpecifyKind(fullApiSet.ReleaseDate, DateTimeKind.Utc)
|
||||
: null;
|
||||
|
||||
var dbSet = new Set
|
||||
{
|
||||
Language = language,
|
||||
Name = setBrief.Name ?? "Unknown",
|
||||
Logo = setBrief.Logo,
|
||||
ReleaseDate = utcReleaseDate,
|
||||
Symbol = setBrief.Symbol,
|
||||
SetInfo = new TcgDexSetInfo { SetId = fullApiSet.Id },
|
||||
CardMarketSetInfo = new CardMarketSetInfo { ExpansionId = "0" }, // TODO: Späterer Price-Scraper
|
||||
Legal = new Legal
|
||||
{
|
||||
Expanded = fullApiSet.Legal?.Expanded ?? false,
|
||||
Standard = fullApiSet.Legal?.Standard ?? false
|
||||
},
|
||||
CardCount = new CardCount
|
||||
{
|
||||
FirstEd = fullApiSet.CardCount?.FirstEd ?? 0,
|
||||
Holo = fullApiSet.CardCount?.Holo ?? 0,
|
||||
Normal = fullApiSet.CardCount?.Normal ?? 0,
|
||||
Official = fullApiSet.CardCount?.Official ?? 0,
|
||||
Reverse = fullApiSet.CardCount?.Reverse ?? 0,
|
||||
Total = fullApiSet.CardCount?.Total ?? 0
|
||||
}
|
||||
};
|
||||
|
||||
if (fullApiSet.Cards is not { Count: > 0 }) return dbSet;
|
||||
|
||||
var cardTasks = fullApiSet.Cards.Select(async c =>
|
||||
{
|
||||
var localPath = await _tcgDexService.DownloadCardImage(c, language.ToApiCode());
|
||||
|
||||
return new Card
|
||||
{
|
||||
Name = c.Name ?? "Unknown",
|
||||
Image = localPath == null ? c.Image : localPath.Item1,
|
||||
CardNumber = c.LocalId ?? 0,
|
||||
PHash = localPath == null ? 0 : PerceptualHashHelper.GenerateHash(localPath.Item2),
|
||||
TcgDexCardInfo = new TcgDexCardInfo
|
||||
{
|
||||
FullId = c.Id ?? string.Empty,
|
||||
LocalId = c.LocalId ?? 0
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
dbSet.Cards = (await Task.WhenAll(cardTasks)).ToList();
|
||||
|
||||
return dbSet;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using OakArchive.Models.TcgDex;
|
||||
|
||||
namespace OakArchive.Services;
|
||||
|
||||
public interface ITcgDexService
|
||||
{
|
||||
public Task<List<SerieBrief>> GetSeries(string language);
|
||||
|
||||
public Task<Serie?> GetSetsOfSeries(string series, string language);
|
||||
|
||||
public Task<Set?> GetSet(string set, string language);
|
||||
|
||||
public Task<Card?> GetCard(string set, int id, string language);
|
||||
|
||||
public Task<Tuple<string, byte[]>?> DownloadCardImage(Card card, string language);
|
||||
}
|
||||
|
||||
public class TcgDexService : ITcgDexService
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly IMemoryCacheService _cacheService;
|
||||
|
||||
private readonly string _baseFolder = Path.Combine(Directory.GetCurrentDirectory(), "Cards");
|
||||
private readonly SemaphoreSlim _downloadSemaphore = new SemaphoreSlim(3, 3);
|
||||
|
||||
public TcgDexService(HttpClient httpClient, IMemoryCacheService cacheService)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_cacheService = cacheService;
|
||||
}
|
||||
|
||||
public async Task<List<SerieBrief>> GetSeries(string language)
|
||||
{
|
||||
var cacheKey = $"tcgdex_series_{language.ToLower()}";
|
||||
|
||||
async Task<List<SerieBrief>> FetchFromApi()
|
||||
{
|
||||
var res = await _httpClient.GetFromJsonAsync<List<SerieBrief>>($"{language}/series");
|
||||
return res ?? [];
|
||||
}
|
||||
|
||||
return await _cacheService.GetOrCreateAsync(cacheKey, FetchFromApi, TimeSpan.FromDays(7));
|
||||
}
|
||||
|
||||
public async Task<Serie?> GetSetsOfSeries(string series, string language)
|
||||
{
|
||||
var cacheKey = $"tcgdex_serie_{series.ToLower()}_{language.ToLower()}";
|
||||
|
||||
async Task<Serie?> FetchFromApi()
|
||||
{
|
||||
var res = await _httpClient.GetFromJsonAsync<Serie>($"{language}/series/{series}");
|
||||
return res;
|
||||
}
|
||||
|
||||
return await _cacheService.GetOrCreateAsync(cacheKey, FetchFromApi, TimeSpan.FromDays(7));
|
||||
}
|
||||
|
||||
public async Task<Set?> GetSet(string set, string language)
|
||||
{
|
||||
var cacheKey = $"tcgdex_set_{set.ToLower()}_{language.ToLower()}";
|
||||
|
||||
async Task<Set?> FetchFromApi()
|
||||
{
|
||||
var res = await _httpClient.GetFromJsonAsync<Set>($"{language}/sets/{set}");
|
||||
return res;
|
||||
}
|
||||
|
||||
return await _cacheService.GetOrCreateAsync(cacheKey, FetchFromApi, TimeSpan.FromDays(7));
|
||||
}
|
||||
|
||||
public async Task<Card?> GetCard(string set, int id, string language)
|
||||
{
|
||||
var cacheKey = $"tcgdex_card_{set.ToLower()}_{language.ToLower()}";
|
||||
|
||||
async Task<Card?> FetchFromApi()
|
||||
{
|
||||
var res = await _httpClient.GetFromJsonAsync<Card?>($"{language}/cards/{set}-{id}");
|
||||
return res;
|
||||
}
|
||||
|
||||
return await _cacheService.GetOrCreateAsync(cacheKey, FetchFromApi, TimeSpan.FromDays(7));
|
||||
}
|
||||
|
||||
public async Task<Tuple<string, byte[]>?> DownloadCardImage(Card card, string language)
|
||||
{
|
||||
var split = card.Id!.Split("-");
|
||||
var filePath = Path.Combine(_baseFolder, split[0], language,$"{split[1]}.webp");
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
var res = await File.ReadAllBytesAsync(filePath);
|
||||
return Tuple.Create(filePath, res);
|
||||
}
|
||||
|
||||
await _downloadSemaphore.WaitAsync();
|
||||
|
||||
try
|
||||
{
|
||||
var res = await _httpClient.GetByteArrayAsync(card.Image + "/high.webp");
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(filePath)!);
|
||||
await File.WriteAllBytesAsync(filePath, res);
|
||||
|
||||
await Task.Delay(200);
|
||||
|
||||
return Tuple.Create(filePath, res);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_downloadSemaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using OakArchive.Entities.Enums;
|
||||
|
||||
namespace OakArchive.Util.Extensions;
|
||||
|
||||
public static class LanguageExtensions
|
||||
{
|
||||
public static string ToApiCode(this Language lang)
|
||||
{
|
||||
return lang switch
|
||||
{
|
||||
Language.Es_Mx => "es-mx",
|
||||
Language.Pt_Br => "pt-br",
|
||||
Language.Pt_Pt => "pt-pt",
|
||||
Language.Zh_Tw => "zh-tw",
|
||||
Language.Zh_Cn => "zh-cn",
|
||||
_ => lang.ToString().ToLower()
|
||||
};
|
||||
}
|
||||
|
||||
// Ein zusätzliches Feld für deine Avalonia-UI (Anzeigename)
|
||||
public static string GetDisplayName(this Language lang)
|
||||
{
|
||||
return lang switch
|
||||
{
|
||||
Language.En => "English",
|
||||
Language.Fr => "Français",
|
||||
Language.Es => "Español",
|
||||
Language.Es_Mx => "Español (México)",
|
||||
Language.It => "Italiano",
|
||||
Language.Pt => "Português",
|
||||
Language.Pt_Br => "Português (Brasil)",
|
||||
Language.Pt_Pt => "Português (Portugal)",
|
||||
Language.De => "Deutsch",
|
||||
Language.Nl => "Nederlands",
|
||||
Language.Pl => "Polski",
|
||||
Language.Ru => "Русский",
|
||||
Language.Ja => "日本語",
|
||||
Language.Ko => "한국어",
|
||||
Language.Zh_Tw => "繁體中文 (Taiwan)",
|
||||
Language.Id => "Bahasa Indonesia",
|
||||
Language.Th => "ไทย",
|
||||
Language.Zh_Cn => "简体中文 (China)",
|
||||
_ => lang.ToString()
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using CoenM.ImageHash.HashAlgorithms;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
|
||||
namespace OakArchive.Util;
|
||||
|
||||
public class PerceptualHashHelper
|
||||
{
|
||||
private static readonly PerceptualHash _perceptualHash = new();
|
||||
|
||||
private const int TargetWidth = 600;
|
||||
private const int TargetHeight = 840;
|
||||
private const int Margin = 15;
|
||||
|
||||
public static ulong GenerateHash(byte[] rawImage)
|
||||
{
|
||||
using var image = Image.Load<Rgba32>(rawImage);
|
||||
|
||||
image.Mutate(x => x.Resize(TargetWidth, TargetHeight));
|
||||
|
||||
return _perceptualHash.Hash(image);
|
||||
}
|
||||
|
||||
public static ulong GenerateHashWithMargin(byte[] rawImage)
|
||||
{
|
||||
using var image = Image.Load<Rgba32>(rawImage);
|
||||
|
||||
const int maxContentWidth = TargetWidth - (2 * Margin);
|
||||
const int maxContentHeight = TargetHeight - (2 * Margin);
|
||||
|
||||
image.Mutate(x => x.Resize(new ResizeOptions
|
||||
{
|
||||
Size = new Size(maxContentWidth, maxContentHeight),
|
||||
Mode = ResizeMode.Max
|
||||
}));
|
||||
|
||||
using var canvas = new Image<Rgba32>(TargetWidth, TargetHeight, Color.Black);
|
||||
|
||||
var posX = (TargetWidth - image.Width) / 2;
|
||||
var posY = (TargetHeight - image.Height) / 2;
|
||||
|
||||
canvas.Mutate(x => x.DrawImage(image, new Point(posX, posY), 1f));
|
||||
|
||||
return _perceptualHash.Hash(canvas);
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -4,13 +4,12 @@
|
||||
build:
|
||||
context: .
|
||||
dockerfile: OakArchive/Dockerfile
|
||||
# Falls die DB in einer anderen Datei ist, nimm depends_on raus,
|
||||
# da Compose nur Services innerhalb derselben Datei überwachen kann.
|
||||
networks:
|
||||
- postgres-network
|
||||
environment:
|
||||
# WICHTIG: Host muss der 'container_name' oder 'service_name' der DB sein
|
||||
- CONNECTION_STRING=Host=OmniDB;Database=oak_db;Username=admin;Password=${DB_PASSWORD}
|
||||
- DefaultConnection=Host=OmniDB;Database=oak_db;Username=admin;Password=${DB_PASSWORD}
|
||||
volumes:
|
||||
- C:\Users\larsh\Documents\docker\oakarchive\Cards:/app/Cards
|
||||
|
||||
networks:
|
||||
postgres-network:
|
||||
|
||||
Reference in New Issue
Block a user