using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Nuuru.Server.Models.Booru { public class TagCategory { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get; set; } = Guid.NewGuid(); [MaxLength(100)] public string Name { get; set; } = null!; // e.g., "Artist" [MaxLength(100)] public string Slug { get; set; } = null!; // normalized, unique: "artist" public string? ColorHex { get; set; } // UI badge color, e.g., "#e57373" public int SortOrder { get; set; } // UI ordering public bool IsActive { get; set; } = true; public int? MaxPerPost { get; set; } // e.g., 1 for artist, null for unlimited public Guid? ParentCategoryId { get; set; } // optional hierarchy public TagCategory? ParentCategory { get; set; } public ICollection Children { get; set; } = new List(); public uint Version { get; set; } public ICollection Tags { get; set; } = new List(); } public class Tag { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid Id { get; set; } = Guid.NewGuid(); [MaxLength(250)] public string Name { get; set; } = string.Empty; //tagme of meta:tagme public TagCategory? Category { get; set; } //meta of meta:tagme public int PostCount { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; public ICollection PostTags { get; set; } = new List(); // Tag aliases - where this tag IS the alias (source) public ICollection AliasesAsSource { get; set; } = new List(); // Tag aliases - where this tag IS the target (canonical) public ICollection AliasesAsTarget { get; set; } = new List(); // Tag implications - where this tag is the antecedent (trigger) public ICollection ImplicationsAsAntecedent { get; set; } = new List(); // Tag implications - where this tag is the consequent (implied) public ICollection ImplicationsAsConsequent { get; set; } = new List(); } }