namespace SwDAL.DTO.RolloutCampaign; /// Multi-target rollout (tracker Thread 6 §39) — delivers one already-Released /// UpgradePackage to many already-provisioned client databases in one action. Delivery itself /// reuses ProvisioningBLL.ProvisionClientDatabase per resolved target — this DTO is pure /// orchestration/tracking on top of that existing primitive, not a new delivery mechanism. public class RolloutCampaignDTO { public int RolloutCampaignId { get; set; } public int PackageId { get; set; } public string? PackageCode { get; set; } // read-only JOIN public int DbModelId { get; set; } public byte TargetScope { get; set; } // 0=AllForDbModel 1=AllOnServer 2=SelectedList public int? TargetServerId { get; set; } public byte CampaignStatus { get; set; } // 0=Draft 1=Scheduled 2=InProgress 3=Completed 4=PartiallyFailed public DateTime? ScheduledStartOn { get; set; } public string? Description { get; set; } // Explicit target list — only meaningful (and required) when TargetScope=SelectedList. // Not persisted on this row itself; consumed once by RolloutCampaignBLL.CreateCampaignAsync // to seed the RolloutTargetDTO rows, mirroring how AttachDdlScriptRequestDTO-style request // DTOs carry one-shot input alongside the entity's own persisted shape. public List? SelectedClientDbIds { get; set; } public short Version { get; set; } public byte Status { get; set; } = 1; public short SortOrder { get; set; } = 9999; public int CreatedById { get; set; } public DateTime CreatedOn { get; set; } public int ModifiedById { get; set; } public DateTime ModifiedOn { get; set; } public byte SourceType { get; set; } = 5; public int TenantId { get; set; } } /// One resolved client database within a campaign — the real per-instance state. public class RolloutTargetDTO { public int RolloutTargetId { get; set; } public int RolloutCampaignId { get; set; } public int ClientDbId { get; set; } public string? ClientDbCode { get; set; } // read-only JOIN public byte TargetStatus { get; set; } // 0=Pending 1=Deferred 2=InProgress 3=Applied 4=Skipped 5=Failed public DateTime? DeferredUntil { get; set; } public string? LastError { get; set; } public DateTime? AppliedOn { get; set; } public short Version { get; set; } public byte Status { get; set; } = 1; public short SortOrder { get; set; } = 9999; public int CreatedById { get; set; } public DateTime CreatedOn { get; set; } public int ModifiedById { get; set; } public DateTime ModifiedOn { get; set; } public byte SourceType { get; set; } = 5; public int TenantId { get; set; } } /// Aggregate rollup returned by GetCampaignStatusAsync — the "X of Y applied, Z /// deferred, W failed" view, not a raw dump of every target row. public class RolloutCampaignStatusDTO { public int RolloutCampaignId { get; set; } public byte CampaignStatus { get; set; } public int TotalTargets { get; set; } public int PendingCount { get; set; } public int DeferredCount { get; set; } public int AppliedCount { get; set; } public int SkippedCount { get; set; } public int FailedCount { get; set; } /// Targets whose ClientDatabase is DeliveryMode=Offline (tracker §53) — due, but /// requiring a real external action (export + SwOfflineApply) before they can be considered /// done, never auto-pushed. A campaign never finalizes to Completed/PartiallyFailed while /// this is nonzero. public int AwaitingManualApplyCount { get; set; } }