using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Novelly.Api.Beats; using Novelly.Api.Chapters; using Novelly.Api.Common; using Novelly.Api.Novels; using Novelly.Api.Tags; namespace Novelly.Api.Characters; public class Character : ISoftDeletable { public Guid Id { get; set; } = Guid.NewGuid(); public Guid NovelId { get; set; } public Novel? Novel { get; set; } public string Name { get; set; } = string.Empty; public CharacterRole Role { get; set; } = CharacterRole.Supporting; public CharacterImportance Importance { get; set; } = CharacterImportance.Supporting; public string? Age { get; set; } public string? Pronouns { get; set; } public string? Occupation { get; set; } public string? Appearance { get; set; } public string? Personality { get; set; } public string? Backstory { get; set; } public string? Motivation { get; set; } public string? Conflict { get; set; } public string? Voice { get; set; } public string? Notes { get; set; } public List Aliases { get; set; } = []; public Guid? SameCharacterAsId { get; set; } public Character? SameCharacterAs { get; set; } public List OtherIdentities { get; set; } = []; public Guid? RevealedInChapterId { get; set; } public Chapter? RevealedInChapter { get; set; } public string? IdentityNote { get; set; } public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset? DeletedAt { get; set; } public List Relationships { get; set; } = []; public List Tags { get; set; } = []; public List ArcStages { get; set; } = []; public List Beats { get; set; } = []; } public class CharacterRelationship { public Guid Id { get; set; } = Guid.NewGuid(); public Guid CharacterId { get; set; } public Character? Character { get; set; } public Guid RelatedCharacterId { get; set; } public Character? RelatedCharacter { get; set; } public string RelationshipType { get; set; } = string.Empty; public string? Description { get; set; } } public class CharacterEntityTypeConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder entity) { entity.Property(c => c.Name).IsRequired().HasMaxLength(200); entity.Property(c => c.Role).HasConversion().HasMaxLength(32); entity.Property(c => c.Importance).HasConversion().HasMaxLength(32); entity.HasIndex(c => c.NovelId); entity.HasIndex(c => c.SameCharacterAsId); entity.HasQueryFilter(c => c.DeletedAt == null); entity.HasMany(c => c.Relationships).WithOne(r => r.Character!) .HasForeignKey(r => r.CharacterId).OnDelete(DeleteBehavior.Cascade); entity.HasMany(c => c.ArcStages).WithOne(s => s.Character!) .HasForeignKey(s => s.CharacterId).OnDelete(DeleteBehavior.Cascade); entity.HasOne(c => c.SameCharacterAs).WithMany(c => c.OtherIdentities) .HasForeignKey(c => c.SameCharacterAsId).OnDelete(DeleteBehavior.SetNull); entity.HasOne(c => c.RevealedInChapter).WithMany() .HasForeignKey(c => c.RevealedInChapterId).OnDelete(DeleteBehavior.SetNull); } } public class CharacterRelationshipEntityTypeConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder entity) { entity.Property(r => r.RelationshipType).IsRequired().HasMaxLength(120); entity.HasOne(r => r.RelatedCharacter).WithMany() .HasForeignKey(r => r.RelatedCharacterId).OnDelete(DeleteBehavior.Restrict); entity.HasQueryFilter(r => r.Character!.DeletedAt == null && r.RelatedCharacter!.DeletedAt == null); } }