73 lines
3.7 KiB
C#
73 lines
3.7 KiB
C#
using QuestionsApi.Models;
|
|
using System.Text.Json;
|
|
|
|
namespace QuestionsApi.Services;
|
|
|
|
public static class DynamicBlueprintResolver
|
|
{
|
|
private static readonly JsonSerializerOptions Json = new(JsonSerializerDefaults.Web);
|
|
|
|
public static List<DynamicQuestionBlueprint> ResolveAll(IEnumerable<DynamicQuestionBlueprint> source)
|
|
{
|
|
var all = source.ToList();
|
|
var resolved = new List<DynamicQuestionBlueprint>();
|
|
foreach (var blueprint in all.OrderBy(value => value.Version))
|
|
{
|
|
if (blueprint.BaseBlueprintVersion <= 0)
|
|
{
|
|
resolved.Add(blueprint);
|
|
continue;
|
|
}
|
|
var baseBlueprint = resolved.FirstOrDefault(value =>
|
|
value.ExternalId == blueprint.ExternalId
|
|
&& value.Version == blueprint.BaseBlueprintVersion)
|
|
?? throw new InvalidDataException(
|
|
$"{blueprint.ExternalId} v{blueprint.Version} base version {blueprint.BaseBlueprintVersion} not found");
|
|
var materialized = Clone(baseBlueprint);
|
|
materialized.Id = null;
|
|
materialized.Version = blueprint.Version;
|
|
materialized.BaseBlueprintVersion = blueprint.BaseBlueprintVersion;
|
|
materialized.QualityStandardVersion = blueprint.QualityStandardVersion;
|
|
materialized.IsPublished = blueprint.IsPublished;
|
|
materialized.EncounterFrame = blueprint.EncounterFrame;
|
|
materialized.SiteOfCare = blueprint.SiteOfCare;
|
|
materialized.BlueprintWeight = blueprint.BlueprintWeight;
|
|
materialized.ConceptIds = blueprint.ConceptIds;
|
|
materialized.PrerequisiteConceptIds = blueprint.PrerequisiteConceptIds;
|
|
materialized.MedicallyReviewedUtc = blueprint.MedicallyReviewedUtc;
|
|
materialized.MedicalReviewExpiresUtc = blueprint.MedicalReviewExpiresUtc;
|
|
materialized.MedicalReviewer = blueprint.MedicalReviewer;
|
|
if (blueprint.Distractors.Count > 0)
|
|
materialized.Distractors = blueprint.Distractors;
|
|
if (blueprint.CaseFamilies.Count > 0)
|
|
materialized.CaseFamilies = blueprint.CaseFamilies.Select(overlay =>
|
|
{
|
|
var baseFamily = baseBlueprint.CaseFamilies.FirstOrDefault(value => value.Id == overlay.BaseFamilyId)
|
|
?? throw new InvalidDataException(
|
|
$"{blueprint.ExternalId} v{blueprint.Version} base family {overlay.BaseFamilyId} not found");
|
|
var family = Clone(baseFamily);
|
|
family.Id = overlay.Id;
|
|
family.BaseFamilyId = overlay.BaseFamilyId;
|
|
family.DifficultyTier = overlay.DifficultyTier;
|
|
family.NominalElo = overlay.NominalElo;
|
|
if (!string.IsNullOrWhiteSpace(family.LeadIn)
|
|
&& family.StemTemplate.EndsWith(family.LeadIn, StringComparison.Ordinal))
|
|
family.StemTemplate = family.StemTemplate[..^family.LeadIn.Length].TrimEnd();
|
|
if (!string.IsNullOrWhiteSpace(overlay.StemTemplate))
|
|
family.StemTemplate = $"{family.StemTemplate} {overlay.StemTemplate}".Trim();
|
|
if (!string.IsNullOrWhiteSpace(overlay.LeadIn))
|
|
family.LeadIn = overlay.LeadIn;
|
|
if (overlay.Distractors.Count > 0)
|
|
family.Distractors = overlay.Distractors;
|
|
return family;
|
|
}).ToList();
|
|
resolved.Add(materialized);
|
|
}
|
|
return resolved;
|
|
}
|
|
|
|
private static T Clone<T>(T value) =>
|
|
JsonSerializer.Deserialize<T>(JsonSerializer.Serialize(value, Json), Json)
|
|
?? throw new InvalidOperationException("Blueprint clone failed.");
|
|
}
|