diff --git a/src/Microsoft.Health.Fhir.Core/Features/Persistence/SoftDeletedFhirPathExtension.cs b/src/Microsoft.Health.Fhir.Core/Features/Persistence/SoftDeletedFhirPathExtension.cs
new file mode 100644
index 0000000000..aba64a3a9a
--- /dev/null
+++ b/src/Microsoft.Health.Fhir.Core/Features/Persistence/SoftDeletedFhirPathExtension.cs
@@ -0,0 +1,19 @@
+// -------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
+// -------------------------------------------------------------------------------------------------
+
+using Microsoft.Health.Fhir.Core.Models;
+
+namespace Microsoft.Health.Fhir.Core.Features.Persistence;
+
+public static class SoftDeletedFhirPathExtension
+{
+ ///
+ /// Return true if this resource contains the Azure 'soft-deleted' extension in meta data
+ ///
+ public static bool IsSoftDeleted(this ResourceElement resourceElement)
+ {
+ return resourceElement.Predicate(KnownFhirPaths.IsSoftDeletedExtension);
+ }
+}
diff --git a/src/Microsoft.Health.Fhir.Core/Models/KnownFhirPaths.cs b/src/Microsoft.Health.Fhir.Core/Models/KnownFhirPaths.cs
index 5685d3a7a1..498cdb8ff0 100644
--- a/src/Microsoft.Health.Fhir.Core/Models/KnownFhirPaths.cs
+++ b/src/Microsoft.Health.Fhir.Core/Models/KnownFhirPaths.cs
@@ -7,6 +7,8 @@ namespace Microsoft.Health.Fhir.Core.Models
{
public static class KnownFhirPaths
{
+ internal const string AzureSoftDeletedExtensionUrl = "http://azurehealthcareapis.com/data-extensions/deleted-state";
+
public const string BundleEntries = "Resource.entry.resource";
public const string BundleNextLink = "Resource.link.where(relation = 'next').url";
@@ -16,5 +18,7 @@ public static class KnownFhirPaths
public const string BundleType = "Resource.type";
public const string ResourceNarrative = "text.div";
+
+ public const string IsSoftDeletedExtension = $"Resource.meta.extension.where(url = '{AzureSoftDeletedExtensionUrl}').where(value='soft-deleted').exists()";
}
}
diff --git a/src/Microsoft.Health.Fhir.Shared.Core.UnitTests/Extensions/KnowFhirPathsTests.cs b/src/Microsoft.Health.Fhir.Shared.Core.UnitTests/Extensions/KnowFhirPathsTests.cs
new file mode 100644
index 0000000000..f523bf475f
--- /dev/null
+++ b/src/Microsoft.Health.Fhir.Shared.Core.UnitTests/Extensions/KnowFhirPathsTests.cs
@@ -0,0 +1,32 @@
+// -------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
+// -------------------------------------------------------------------------------------------------
+
+using Microsoft.Health.Fhir.Core.Extensions;
+using Microsoft.Health.Fhir.Core.Features.Persistence;
+using Microsoft.Health.Fhir.Core.Models;
+using Microsoft.Health.Fhir.Tests.Common;
+using Microsoft.Health.Test.Utilities;
+using Xunit;
+
+namespace Microsoft.Health.Fhir.Shared.Core.UnitTests.Extensions;
+
+[Trait(Traits.OwningTeam, OwningTeam.Fhir)]
+[Trait(Traits.Category, Categories.Import)]
+public class KnowFhirPathsTests
+{
+ [Fact]
+ public void GivenAResource_WhenEvaluatingIfSoftDeleted_ThenTheCorrectFlagIsReturned()
+ {
+ ResourceElement patient = Samples.GetDefaultPatient();
+
+ var isDeleted = patient.IsSoftDeleted();
+ Assert.False(isDeleted);
+
+ ResourceElement withExtension = patient.TryAddSoftDeletedExtension();
+
+ isDeleted = withExtension.IsSoftDeleted();
+ Assert.True(isDeleted);
+ }
+}
diff --git a/src/Microsoft.Health.Fhir.Shared.Core.UnitTests/Microsoft.Health.Fhir.Shared.Core.UnitTests.projitems b/src/Microsoft.Health.Fhir.Shared.Core.UnitTests/Microsoft.Health.Fhir.Shared.Core.UnitTests.projitems
index af51a256fb..d9d8c9cc7b 100644
--- a/src/Microsoft.Health.Fhir.Shared.Core.UnitTests/Microsoft.Health.Fhir.Shared.Core.UnitTests.projitems
+++ b/src/Microsoft.Health.Fhir.Shared.Core.UnitTests/Microsoft.Health.Fhir.Shared.Core.UnitTests.projitems
@@ -10,6 +10,7 @@
+
diff --git a/src/Microsoft.Health.Fhir.Shared.Core/Extensions/ModelExtensions.cs b/src/Microsoft.Health.Fhir.Shared.Core/Extensions/ModelExtensions.cs
index 3f976bad19..88187468e2 100644
--- a/src/Microsoft.Health.Fhir.Shared.Core/Extensions/ModelExtensions.cs
+++ b/src/Microsoft.Health.Fhir.Shared.Core/Extensions/ModelExtensions.cs
@@ -130,6 +130,26 @@ public static ResourceElement UpdateLastUpdated(this ResourceElement resource, D
return poco.ToResourceElement();
}
+ public static ResourceElement TryAddSoftDeletedExtension(this ResourceElement resource)
+ {
+ EnsureArg.IsNotNull(resource, nameof(resource));
+
+ Resource poco = resource.ToPoco();
+ poco.Meta ??= new Meta();
+
+ if (!poco.Meta.Extension.Any(x => string.Equals(x.Url, KnownFhirPaths.AzureSoftDeletedExtensionUrl, StringComparison.OrdinalIgnoreCase)))
+ {
+ poco.Meta.Extension.Add(
+ new Extension
+ {
+ Url = KnownFhirPaths.AzureSoftDeletedExtensionUrl,
+ Value = new FhirString("soft-deleted"),
+ });
+ }
+
+ return poco.ToResourceElement();
+ }
+
public static SearchParameterInfo ToInfo(this SearchParameter searchParam)
{
EnsureArg.IsNotNull(searchParam, nameof(searchParam));