Files
step3/api/QuestionsApi/Services/DynamicBlueprintResolver.cs
T

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.");
}