using System.ComponentModel.DataAnnotations; namespace GerbilManagerWebAPI.Models { /// Publication state of a CMS page (serialised as string name). public enum PageStatus { Draft = 0, Published = 1, } /// /// CMS block kinds. RichText holds MARKDOWN (sanitised on render). AbgabetiereList is /// dynamic — resolved from live ForSale animals at snapshot time. Serialised as string. /// public enum BlockType { Heading = 0, RichText = 1, Image = 2, Gallery = 3, ContactInfo = 4, AbgabetiereList = 5, } /// Singleton site settings (WEB epic CMS). public class Site { /// Fixed id — there is exactly one Site row. public static readonly Guid SingletonId = new("5172e000-0000-0000-0000-000000000001"); [Key] public Guid Id { get; set; } public string DefaultLocale { get; set; } = "de"; /// Ordered page ids for the public nav (JSON list). public List NavOrder { get; set; } = new(); } /// A CMS page (one of the public website's pages). public class Page { [Key] public Guid Id { get; set; } /// Stable URL slug (e.g. "abgabetiere") — the human key. public required string Slug { get; set; } public required string Title { get; set; } public string? SeoDescription { get; set; } public PageStatus Status { get; set; } = PageStatus.Draft; public ICollection Blocks { get; } = new List(); } /// /// A content block on a page (single table, discriminated by ). /// Type-specific payload lives in as JSON (RichText = Markdown). /// public class Block { [Key] public Guid Id { get; set; } public Guid PageId { get; set; } /// Explicit ordering within the page (AI tools reorder by this). public int Order { get; set; } public BlockType Type { get; set; } /// Type-specific fields as a JSON object string. public string Data { get; set; } = "{}"; } /// A media asset referenced by Image/Gallery blocks. public class Media { [Key] public Guid Id { get; set; } public required string FileName { get; set; } public required string Url { get; set; } public string? Alt { get; set; } public int? Width { get; set; } public int? Height { get; set; } } }