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