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; }
}
}