using System; using System.Collections.Generic; namespace GB5Shared.DTO.Promotion { // ============================================================ // PromotionBundleDTO — the exported snapshot of one promotable object // (+ its known children), moved between deployments as the payload of a // GOP Promotion flow and/or an Exchange package. See // /Users/venkatv/.claude/plans/as-part-of-developement-indexed-stonebraker.md // // Identity across deployments is (OriginEnvironmentCode, EntityTypeCode, // OriginEntityId) — never a raw numeric ID alone, since AutoNumber-assigned // IDs mean nothing across two separate physical databases. // ============================================================ public class PromotionBundleDTO { public string OriginEnvironmentCode { get; set; } = string.Empty; public string EntityTypeCode { get; set; } = string.Empty; // MPROMOTABLEENTITYTYPE.ENTITYTYPECODE public int OriginEntityId { get; set; } /// The exported object's own DTO, serialized as JSON by the owning /// IPromotableEntity implementation — shape is entity-specific, opaque here. public string PayloadJson { get; set; } = string.Empty; /// Serialized child rows (e.g. Menu -> MenuGroupDetail), one entry per /// child collection, entity-specific in shape — opaque here, interpreted only by /// the IPromotableEntity implementation that produced/consumes it. public Dictionary ChildPayloadsJson { get; set; } = new(); public int SubmittedByUserId { get; set; } public string? SubmittedByUserName { get; set; } public DateTime SubmittedOn { get; set; } /// Submitter's own claim about shareability — re-checked independently by /// the addon-reference validator at both export and ingest time, never trusted alone. public bool SubmitterClaimsShareable { get; set; } = true; /// Reserved for the future "early packet ahead of a full release" extension /// (see the plan's Generalizing section) — unused by Promotion itself today, but part /// of the manifest from the start so it isn't a breaking format change later. public string? ReleaseVersion { get; set; } } // ============================================================ // PromotionValidationResultDTO — returned by IPromotableEntity.ValidateForPromotionAsync, // re-run independently at both export time (fail fast for the submitter) and ingest time // (never trust only the origin's copy of the validator). // ============================================================ public class PromotionValidationResultDTO { public bool IsPromotable { get; set; } = true; public List BlockingReasons { get; set; } = new(); public List Warnings { get; set; } = new(); public static PromotionValidationResultDTO Ok() => new() { IsPromotable = true }; public static PromotionValidationResultDTO Block(string reason) => new() { IsPromotable = false, BlockingReasons = new List { reason } }; } }