namespace RecruitmentDAL.DTO.Reports { // Phase 5 analytics — DEI/diversity sourcing report. Raw, UN-suppressed row shape as it comes // back from SQL — one row per (DemographicDimension, DemographicValue, Source) group, built // from MCANDIDATEDEMOGRAPHIC WHERE CONSENTTOCOLLECT = 1 only (see DeiSourcingReportQB). // // THIS TYPE MUST NEVER BE RETURNED DIRECTLY FROM THE BLL OR THE ENDPOINT. It exists only as // the DAL's internal query-result shape. DeiSourcingReportBLL.ApplyCellSuppression converts // every row of this type into a DeiSourcingReportDTO (below) — the only type that ever leaves // the BLL — enforcing the mandatory <5-candidate cell-suppression rule in the process. Adding // a new caller that reads this raw type and skips DeiSourcingReportBLL would defeat the // report's entire privacy safeguard; don't do that. public class DeiSourcingReportRawDTO { public string DemographicDimension { get; set; } = string.Empty; public string DemographicValue { get; set; } = string.Empty; public byte Source { get; set; } public string SourceName { get; set; } = string.Empty; public int CandidateCount { get; set; } public int AppliedCount { get; set; } // Distinct Applications in this group that reached (have stage-history for) any // Interview-category (StageCategory=3) stage at least once. public int InterviewedCount { get; set; } // Distinct Applications in this group that are "genuinely Hired" — same structural // signal as CandidateConversionBLL / CandidateSourceQualityDTO.HiredCount / ApplicationCycleTimeDTO.IsHired: // current stage Terminal (StageCategory=7, IsTerminal=1) AND most recent stage-history // row for that stage has Outcome=Passed(2). public int HiredCount { get; set; } } // Public, cell-suppressed report row — the ONLY shape this report ever returns to a caller // (paged JSON, export, or NDJSON stream alike). Count fields are strings deliberately: once // cell-suppression replaces a small exact count with a placeholder (e.g. "<5"), the field can // no longer be a plain int — see DeiSourcingReportBLL.ApplyCellSuppression for the exact rule // and threshold (5), enforced once, in this one place, before any row leaves the BLL. public class DeiSourcingReportDTO { public string DemographicDimension { get; set; } = string.Empty; public string DemographicValue { get; set; } = string.Empty; public byte Source { get; set; } public string SourceName { get; set; } = string.Empty; public string CandidateCount { get; set; } = "0"; public string AppliedCount { get; set; } = "0"; public string InterviewedCount { get; set; } = "0"; public string HiredCount { get; set; } = "0"; } }