diff --git a/.docker/linux/Mongo.R6.Dockerfile b/.docker/linux/Mongo.R6.Dockerfile
new file mode 100644
index 000000000..d540d4b1b
--- /dev/null
+++ b/.docker/linux/Mongo.R6.Dockerfile
@@ -0,0 +1,9 @@
+FROM mongo:8.2.12@sha256:e0ce8c35124d4a9f9785532d1f268f39e9728ffa1cb38f46fa482436424c4bd3
+
+ENV ARCHIVE=/home/r6.archive.gz
+
+COPY .docker/linux/r6.archive.gz /home/
+COPY .docker/linux/mongorestore.sh /docker-entrypoint-initdb.d/
+
+RUN chmod +x /docker-entrypoint-initdb.d/mongorestore.sh
+
diff --git a/.docker/linux/Spark.R6.Dockerfile b/.docker/linux/Spark.R6.Dockerfile
new file mode 100644
index 000000000..682d3553b
--- /dev/null
+++ b/.docker/linux/Spark.R6.Dockerfile
@@ -0,0 +1,63 @@
+FROM mcr.microsoft.com/dotnet/aspnet:10.0-alpine@sha256:1b3a34768687d583ebdf16ca8dd9a21ec93de9cdf81bb424e3c1a706e2a453d7 AS base
+
+RUN apk add --no-cache icu-libs
+ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
+WORKDIR /app
+ENV ASPNETCORE_URLS=http://+:80
+
+
+FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine@sha256:d8ee39817ca03a3757288e83c37ed73cc969a286c603b827c7cbe33add1c2d1c AS build-deps
+
+RUN apk add --no-cache nodejs npm
+
+
+FROM build-deps AS npm-restore
+
+WORKDIR /Applications/Spark.Web.Shared/app
+
+COPY ["./Applications/Spark.Web.Shared/app/package.json", "./"]
+COPY ["./Applications/Spark.Web.Shared/app/package-lock.json", "./"]
+
+RUN npm ci
+
+
+FROM build-deps AS dotnet-restore
+
+WORKDIR /src
+
+COPY ["./Directory.Build.props", "../Directory.Build.props"]
+COPY ["./Libraries/Spark.Engine/Spark.Engine.csproj", "Libraries/Spark.Engine/Spark.Engine.csproj"]
+COPY ["./Libraries/Spark.Store.MongoDB/Spark.Store.MongoDB.csproj", "Libraries/Spark.Store.MongoDB/Spark.Store.MongoDB.csproj"]
+COPY ["./Libraries/Spark.Engine.R6/Spark.Engine.R6.csproj", "Libraries/Spark.Engine.R6/Spark.Engine.R6.csproj"]
+COPY ["./Applications/Spark.Web.R6/Spark.Web.R6.csproj", "Applications/Spark.Web.R6/Spark.Web.R6.csproj"]
+
+RUN dotnet restore "Applications/Spark.Web.R6/Spark.Web.R6.csproj"
+
+
+FROM dotnet-restore AS build
+
+WORKDIR /src
+
+COPY --from=npm-restore /Applications/Spark.Web.Shared/app/node_modules ./Applications/Spark.Web.Shared/app/node_modules
+
+COPY ["./Libraries/Spark.Engine/", "Libraries/Spark.Engine/"]
+COPY ["./Libraries/Spark.Store.MongoDB/", "Libraries/Spark.Store.MongoDB/"]
+COPY ["./Libraries/Spark.Engine.R6/", "Libraries/Spark.Engine.R6/"]
+COPY ["./Libraries/Spark.Engine.Shared/", "Libraries/Spark.Engine.Shared/"]
+COPY ["./Applications/Spark.Web.Shared/", "Applications/Spark.Web.Shared/"]
+COPY ["./Applications/Spark.Web.R6/", "Applications/Spark.Web.R6/"]
+
+
+FROM build AS publish
+
+
+RUN dotnet publish "Applications/Spark.Web.R6/Spark.Web.R6.csproj" -c Release -o /app/publish --no-restore
+
+
+FROM base AS final
+
+WORKDIR /app
+
+COPY --from=publish /app/publish .
+
+ENTRYPOINT ["dotnet", "Spark.Web.R6.dll"]
diff --git a/Applications/Spark.Web.R6/.gitignore b/Applications/Spark.Web.R6/.gitignore
new file mode 100644
index 000000000..f6b5ef9ec
--- /dev/null
+++ b/Applications/Spark.Web.R6/.gitignore
@@ -0,0 +1,7 @@
+database.db
+database.db-shm
+database.db-wal
+
+# generated frontend files
+wwwroot/assets/
+wwwroot/index.html
diff --git a/Applications/Spark.Web.R6/Properties/.gitignore b/Applications/Spark.Web.R6/Properties/.gitignore
new file mode 100644
index 000000000..60c979a0b
--- /dev/null
+++ b/Applications/Spark.Web.R6/Properties/.gitignore
@@ -0,0 +1,2 @@
+serviceDependencies.json
+serviceDependencies.local.json
diff --git a/Applications/Spark.Web.R6/Properties/launchSettings.json b/Applications/Spark.Web.R6/Properties/launchSettings.json
new file mode 100644
index 000000000..bd872817e
--- /dev/null
+++ b/Applications/Spark.Web.R6/Properties/launchSettings.json
@@ -0,0 +1,29 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:54460",
+ "sslPort": 44305
+ }
+ },
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Spark.Web.R6": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:5001;http://localhost:5000"
+ }
+ }
+}
diff --git a/Applications/Spark.Web.R6/Settings/appsettings.json b/Applications/Spark.Web.R6/Settings/appsettings.json
new file mode 100644
index 000000000..f7a234615
--- /dev/null
+++ b/Applications/Spark.Web.R6/Settings/appsettings.json
@@ -0,0 +1,22 @@
+{
+ "StoreSettings": {
+ "ConnectionString": "mongodb://localhost:27017/spark"
+ },
+ "SparkSettings": {
+ "Endpoint": "https://localhost:5001/fhir"
+ },
+ "GitHub": {
+ "ClientId": "",
+ "ClientSecret": "",
+ "AdminUsers": ["your-github-username"]
+ },
+ "ExamplesSettings": {
+ "FilePath": "Examples/R6/examples.zip"
+ },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/Applications/Spark.Web.R6/Spark.Web.R6.csproj b/Applications/Spark.Web.R6/Spark.Web.R6.csproj
new file mode 100644
index 000000000..92aa0ce9f
--- /dev/null
+++ b/Applications/Spark.Web.R6/Spark.Web.R6.csproj
@@ -0,0 +1,43 @@
+
+
+
+ net10.0
+ Spark.Web.R6
+ Spark.Web
+ AspNetCoreModuleV2
+ a4d3c2a3-5edd-47d1-8407-62489d5568c5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Examples/R6/examples.zip
+ Always
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Applications/Spark.Web.Shared/Examples/R6/examples.zip b/Applications/Spark.Web.Shared/Examples/R6/examples.zip
new file mode 100644
index 000000000..d27394e3a
Binary files /dev/null and b/Applications/Spark.Web.Shared/Examples/R6/examples.zip differ
diff --git a/Libraries/Spark.Engine.R6/Core/FhirModel.cs b/Libraries/Spark.Engine.R6/Core/FhirModel.cs
new file mode 100644
index 000000000..ea7098551
--- /dev/null
+++ b/Libraries/Spark.Engine.R6/Core/FhirModel.cs
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015-2018, Firely
+ * Copyright (c) 2017-2026, Incendi
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+using Hl7.Fhir.Introspection;
+using Hl7.Fhir.Model;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Spark.Engine.Core;
+
+public class FhirModel : FhirModelBase
+{
+ // This constructor is only supposed to be accessed by tests and is therefore marked as internal.
+ internal FhirModel(Dictionary resourceTypeToResourceTypeNameMapping, IEnumerable searchParameters)
+ : base(resourceTypeToResourceTypeNameMapping, searchParameters) { }
+
+ public FhirModel() : base(ModelInfo.SearchParameters) { }
+
+ public FhirModel(IEnumerable searchParameters) : base(searchParameters) { }
+
+ // FIXME: Related issue: https://github.com/FirelyTeam/firely-net-sdk/issues/3573
+ public override IReadOnlyList SupportedResources =>
+ ModelInfo.SupportedResources
+ .Where(resource => resource != "ClinicalAssessment"
+ && resource != "DeviceAlert"
+ && resource != "InsuranceProduct"
+ && resource != "MolecularDefinition"
+ && resource != "PersonalRelationship")
+ .ToArray();
+
+ public override string FhirRelease => ModelInfo.Version;
+
+ public override ModelInspector GetModelInspector() => ModelInfo.ModelInspector;
+
+ public override Type GetTypeForFhirType(string typeName) => ModelInfo.GetTypeForFhirType(typeName);
+
+ public override string GetFhirTypeNameForType(Type type) => ModelInfo.GetFhirTypeNameForType(type);
+
+ protected override SearchParamDefinition[] GetGenericSearchParamDefinitions()
+ {
+ return [
+ new()
+ {
+ Resource = "Resource",
+ Name = "_id",
+ Type = SearchParamType.Token,
+ Expression = "Resource.id",
+ Path = ["Resource.id"]
+ },
+ new()
+ {
+ Resource = "Resource",
+ Name = "_lastUpdated",
+ Type = SearchParamType.Date,
+ Expression = "Resource.meta.lastUpdated",
+ Path = ["Resource.meta.lastUpdated"]
+ },
+ new()
+ {
+ Resource = "Resource",
+ Name = "_tag",
+ Type = SearchParamType.Token,
+ Expression = "Resource.meta.tag",
+ Path = ["Resource.meta.tag"]
+ },
+ new()
+ {
+ Resource = "Resource",
+ Name = "_profile",
+ Type = SearchParamType.Reference,
+ Expression = "Resource.meta.profile",
+ Path = ["Resource.meta.profile"]
+ },
+ new()
+ {
+ Resource = "Resource",
+ Name = "_security",
+ Type = SearchParamType.Token,
+ Expression = "Resource.meta.security",
+ Path = ["Resource.meta.security"]
+ },
+ new()
+ {
+ Resource = "Resource",
+ Name = "_source",
+ Type = SearchParamType.Uri,
+ Expression = "Resource.meta.source",
+ Path = ["Resource.meta.source"]
+ }
+ ];
+ }
+}
diff --git a/Libraries/Spark.Engine.R6/Extensions/IServiceCollectionExtensions.cs b/Libraries/Spark.Engine.R6/Extensions/IServiceCollectionExtensions.cs
new file mode 100644
index 000000000..b1df5c69f
--- /dev/null
+++ b/Libraries/Spark.Engine.R6/Extensions/IServiceCollectionExtensions.cs
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2026, Incendi
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+using Hl7.Fhir.Model;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Spark.Engine.Core;
+using Spark.Engine.Service.FhirServiceExtensions;
+using Hl7.Fhir.Specification;
+using Spark.Engine.Search;
+using Spark.Engine.Service;
+using System;
+
+namespace Spark.Engine.Extensions;
+
+public static class IServiceCollectionExtensions
+{
+ public static IMvcBuilder AddFhirWithMvc(this IServiceCollection services, SparkSettings settings, Action setupAction = null)
+ {
+ services.TryAddSingleton(_ => new FhirModel(ModelInfo.SearchParameters));
+ services.TryAddSingleton();
+ services.TryAddTransient();
+ services.TryAddSingleton(provider => new CapabilityStatementService(
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ FHIRVersion.N6_0_0));
+ services.TryAddSingleton(provider =>
+ new ResourceResolver(
+ provider.GetRequiredService().SupportedResources,
+ new PocoStructureDefinitionSummaryProvider()
+ )
+ );
+ services.AddTransient((provider) => new IFhirServiceExtension[]
+ {
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ });
+
+ return services.AddFhirWithMvcInternal(settings, setupAction);
+ }
+}
diff --git a/Libraries/Spark.Engine.R6/Properties/AssemblyInfo.cs b/Libraries/Spark.Engine.R6/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..ae40a2e3a
--- /dev/null
+++ b/Libraries/Spark.Engine.R6/Properties/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2026, Incendi
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("Spark.Engine.R6.Tests")]
+[assembly: InternalsVisibleTo("Spark.Store.MongoDB.Tests")]
diff --git a/Libraries/Spark.Engine.R6/Search/ElementIndexer.cs b/Libraries/Spark.Engine.R6/Search/ElementIndexer.cs
new file mode 100644
index 000000000..0d5058db8
--- /dev/null
+++ b/Libraries/Spark.Engine.R6/Search/ElementIndexer.cs
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2026, Incendi
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+using System.Collections.Generic;
+using Hl7.Fhir.Model;
+using Spark.Engine.Core;
+using Spark.Engine.Model;
+using Spark.Engine.Search.Types;
+using Expression = Spark.Engine.Search.Types.Expression;
+
+namespace Spark.Engine.Search;
+
+public class ElementIndexer : BaseElementIndexer
+{
+ public ElementIndexer(IFhirModel fhirModel, IReferenceNormalizationService referenceNormalizationService = null)
+ : base(fhirModel, referenceNormalizationService)
+ {
+ }
+
+ protected List ToExpressions(Age element)
+ {
+ return element == null ? null : ToExpressions(element as Quantity);
+ }
+
+ protected List ToExpressions(Location.PositionComponent element)
+ {
+ if (element?.Latitude == null)
+ return null;
+ if (element.Longitude == null)
+ return null;
+
+ var position = new List
+ {
+ new("latitude", new NumberValue(element.Latitude.Value)),
+ new("longitude", new NumberValue(element.Longitude.Value))
+ };
+
+ return ListOf(new CompositeValue(position));
+ }
+
+ protected List ToExpressions(Timing element)
+ {
+ if (element?.Repeat?.Bounds == null)
+ return null;
+
+ // TODO: Should I handle Duration?
+ return ToExpressions(element.Repeat.Bounds as Period);
+ }
+}
diff --git a/Libraries/Spark.Engine.R6/Service/FhirServiceR6.cs b/Libraries/Spark.Engine.R6/Service/FhirServiceR6.cs
new file mode 100644
index 000000000..e1b91874c
--- /dev/null
+++ b/Libraries/Spark.Engine.R6/Service/FhirServiceR6.cs
@@ -0,0 +1,29 @@
+using Spark.Engine.Core;
+using Spark.Engine.FhirResponseFactory;
+using Spark.Engine.Service.FhirServiceExtensions;
+using System.Threading.Tasks;
+
+namespace Spark.Engine.Service;
+
+public class FhirServiceR6 : FhirService
+{
+ public FhirServiceR6(
+ IFhirModel fhirModel,
+ IFhirServiceExtension[] extensions,
+ IFhirResponseFactory responseFactory,
+ ICompositeServiceListener serviceListener = null) : base(
+ fhirModel,
+ extensions,
+ responseFactory,
+ serviceListener
+ )
+ {
+ }
+
+ public override Task CapabilityStatementAsync(string sparkVersion)
+ {
+ var capabilityStatementService = GetFeature();
+ var response = Respond.WithResource(capabilityStatementService.GetSparkCapabilityStatement());
+ return Task.FromResult(response);
+ }
+}
diff --git a/Libraries/Spark.Engine.R6/Spark.Engine.R6.csproj b/Libraries/Spark.Engine.R6/Spark.Engine.R6.csproj
new file mode 100644
index 000000000..da1b71981
--- /dev/null
+++ b/Libraries/Spark.Engine.R6/Spark.Engine.R6.csproj
@@ -0,0 +1,47 @@
+
+
+
+ net8.0;net9.0;net10.0
+ Spark.Engine.R6
+ latest
+ Spark.Engine.R6
+ Spark.Engine.R6
+ FHIR R6 Server Engine - R6-specific model, builders, and DI extensions
+ Spark.Engine
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Core\CapabilityStatementBuilder.cs
+
+
+ Core\MessagingComponentBuilder.cs
+
+
+ Core\ResourceComponentBuilder.cs
+
+
+ Core\RestComponentBuilder.cs
+
+
+ Service\FhirServiceExtensions\CapabilityStatementService.cs
+
+
+ Service\FhirServiceExtensions\ICapabilityStatementService.cs
+
+
+
+
diff --git a/Libraries/Spark.Engine/Properties/AssemblyInfo.cs b/Libraries/Spark.Engine/Properties/AssemblyInfo.cs
index 606ff68e4..21e5abbea 100644
--- a/Libraries/Spark.Engine/Properties/AssemblyInfo.cs
+++ b/Libraries/Spark.Engine/Properties/AssemblyInfo.cs
@@ -10,10 +10,12 @@
[assembly: InternalsVisibleTo("Spark.Engine.R4.Tests")]
[assembly: InternalsVisibleTo("Spark.Engine.R4B.Tests")]
[assembly: InternalsVisibleTo("Spark.Engine.R5.Tests")]
+[assembly: InternalsVisibleTo("Spark.Engine.R6.Tests")]
[assembly: InternalsVisibleTo("Spark.Engine.Tests")]
[assembly: InternalsVisibleTo("Spark.Engine.R4")]
[assembly: InternalsVisibleTo("Spark.Engine.R4B")]
[assembly: InternalsVisibleTo("Spark.Engine.R5")]
+[assembly: InternalsVisibleTo("Spark.Engine.R6")]
[assembly: InternalsVisibleTo("Spark.Engine.STU3")]
[assembly: InternalsVisibleTo("Spark.Engine.STU3.Tests")]
[assembly: InternalsVisibleTo("Spark.Store.MongoDB")]
diff --git a/README.md b/README.md
index 32e2031a2..be4b7c23e 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,9 @@ Read [the Quickstart Tutorial](Documentation/Quickstart.md) on how to set up you
#### Docker images
Set up the Spark FHIR server by using the Docker Images. Make sure you have installed [Docker](https://docs.docker.com/install/). On Linux you will need to install [Docker Compose](https://docs.docker.com/compose/install/) as well. After installing Docker you could run Spark server by running one of the following commands, found below, for your preferred FHIR Version. Remember to replace the single quotes with double quotes on Windows. The Spark FHIR Server will be available after startup at `http://localhost:5555`.
+#### R6
+Build from source with `.docker/linux/Spark.R6.Dockerfile` and `.docker/linux/Mongo.R6.Dockerfile`.
+
#### R5
Build from source with `.docker/linux/Spark.R5.Dockerfile` and `.docker/linux/Mongo.R5.Dockerfile`.
@@ -36,6 +39,9 @@ docker-compose up`
## Versions
+#### R6
+Source code can be found in the branch **master**.
+
#### R5
Source code can be found in the branch **master**.
diff --git a/Spark.sln b/Spark.sln
index f9feab50a..64b830d91 100644
--- a/Spark.sln
+++ b/Spark.sln
@@ -47,6 +47,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "linux", "linux", "{152C561B
.docker\linux\Mongo.R5.Dockerfile = .docker\linux\Mongo.R5.Dockerfile
.docker\linux\Spark.R5.Dockerfile = .docker\linux\Spark.R5.Dockerfile
.docker\linux\r5.archive.gz = .docker\linux\r5.archive.gz
+ .docker\linux\Mongo.R6.Dockerfile = .docker\linux\Mongo.R6.Dockerfile
+ .docker\linux\Spark.R6.Dockerfile = .docker\linux\Spark.R6.Dockerfile
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{36B3A784-1A43-4DDE-8BE9-18D198113729}"
@@ -251,6 +253,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spark.Engine.R5.Tests", "Te
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spark.Web.R5.Tests", "Tests\Spark.Web.R5.Tests\Spark.Web.R5.Tests.csproj", "{968CA422-06D5-4354-94EB-8DCC9F9716D4}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spark.Engine.R6", "Libraries\Spark.Engine.R6\Spark.Engine.R6.csproj", "{A89A6433-42CC-4177-87E5-797ACE55585C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spark.Web.R6", "Applications\Spark.Web.R6\Spark.Web.R6.csproj", "{B720C99A-75C9-4D49-BB67-DB2E30296763}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spark.Engine.R6.Tests", "Tests\Spark.Engine.R6.Tests\Spark.Engine.R6.Tests.csproj", "{1653667B-BA9C-48E5-9827-727E78B38387}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spark.Web.R6.Tests", "Tests\Spark.Web.R6.Tests\Spark.Web.R6.Tests.csproj", "{4A138A2A-8E0F-4EF4-874B-C94594362412}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -501,6 +511,54 @@ Global
{968CA422-06D5-4354-94EB-8DCC9F9716D4}.Release|x64.Build.0 = Release|Any CPU
{968CA422-06D5-4354-94EB-8DCC9F9716D4}.Release|x86.ActiveCfg = Release|Any CPU
{968CA422-06D5-4354-94EB-8DCC9F9716D4}.Release|x86.Build.0 = Release|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Debug|x64.Build.0 = Debug|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Debug|x86.Build.0 = Debug|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Release|x64.ActiveCfg = Release|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Release|x64.Build.0 = Release|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Release|x86.ActiveCfg = Release|Any CPU
+ {A89A6433-42CC-4177-87E5-797ACE55585C}.Release|x86.Build.0 = Release|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Debug|x64.Build.0 = Debug|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Debug|x86.Build.0 = Debug|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Release|x64.ActiveCfg = Release|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Release|x64.Build.0 = Release|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Release|x86.ActiveCfg = Release|Any CPU
+ {B720C99A-75C9-4D49-BB67-DB2E30296763}.Release|x86.Build.0 = Release|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Debug|x64.Build.0 = Debug|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Debug|x86.Build.0 = Debug|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Release|x64.ActiveCfg = Release|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Release|x64.Build.0 = Release|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Release|x86.ActiveCfg = Release|Any CPU
+ {1653667B-BA9C-48E5-9827-727E78B38387}.Release|x86.Build.0 = Release|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Debug|x64.Build.0 = Debug|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Debug|x86.Build.0 = Debug|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Release|x64.ActiveCfg = Release|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Release|x64.Build.0 = Release|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Release|x86.ActiveCfg = Release|Any CPU
+ {4A138A2A-8E0F-4EF4-874B-C94594362412}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -550,6 +608,10 @@ Global
{9DAF01D2-63E2-4251-87FE-85F4FA7A5A7F} = {410B602F-CC8D-4DE3-8ADC-89B11A1370D3}
{0B9AC205-FF8C-47E7-BC64-6EC53FC76399} = {95F8DCEC-B674-4B8D-8AE8-9F84785A9204}
{968CA422-06D5-4354-94EB-8DCC9F9716D4} = {95F8DCEC-B674-4B8D-8AE8-9F84785A9204}
+ {A89A6433-42CC-4177-87E5-797ACE55585C} = {DE8AEADA-4B94-495E-8DDB-221F5153533A}
+ {B720C99A-75C9-4D49-BB67-DB2E30296763} = {410B602F-CC8D-4DE3-8ADC-89B11A1370D3}
+ {1653667B-BA9C-48E5-9827-727E78B38387} = {95F8DCEC-B674-4B8D-8AE8-9F84785A9204}
+ {4A138A2A-8E0F-4EF4-874B-C94594362412} = {95F8DCEC-B674-4B8D-8AE8-9F84785A9204}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B5F4527D-CCCF-4487-9E2D-D324DF3552E8}
diff --git a/Tests/Spark.Engine.R6.Tests/AssemblyInfo.cs b/Tests/Spark.Engine.R6.Tests/AssemblyInfo.cs
new file mode 100644
index 000000000..edba69b80
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/AssemblyInfo.cs
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2025, Incendi
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+using Xunit;
+
+[assembly: CollectionBehavior(CollectionBehavior.CollectionPerClass)]
diff --git a/Tests/Spark.Engine.R6.Tests/Core/Builders/CapabilityStatementBuilderTests.Version.cs b/Tests/Spark.Engine.R6.Tests/Core/Builders/CapabilityStatementBuilderTests.Version.cs
new file mode 100644
index 000000000..c9e399909
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Core/Builders/CapabilityStatementBuilderTests.Version.cs
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2026, Incendi
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+using Hl7.Fhir.Model;
+using Spark.Engine.Core;
+
+namespace Spark.Engine.Tests.Core;
+
+public partial class CapabilityStatementBuilderTests
+{
+ private static CapabilityStatementBuilder WithVersionSpecificFhirVersion(CapabilityStatementBuilder builder)
+ => builder.WithFhirVersion(FHIRVersion.N6_0_0);
+
+ private static bool IsPatientResource(CapabilityStatement.ResourceComponent resource)
+ => resource.Type == "Patient";
+
+ private static bool IsDocumentReferenceResource(CapabilityStatement.ResourceComponent resource)
+ => resource.Type == "DocumentReference";
+}
diff --git a/Tests/Spark.Engine.R6.Tests/Core/FhirModelTests.VersionIndependentResourceTypes.cs b/Tests/Spark.Engine.R6.Tests/Core/FhirModelTests.VersionIndependentResourceTypes.cs
new file mode 100644
index 000000000..280364c8a
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Core/FhirModelTests.VersionIndependentResourceTypes.cs
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2026, Incendi
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+using Hl7.Fhir.Model;
+using System;
+using System.Linq;
+using Xunit;
+
+namespace Spark.Engine.Tests;
+
+public class FhirModelVersionIndependentResourceTypesTests
+{
+ [Fact]
+ public void SupportedResources_AreRepresentedByVersionIndependentResourceTypesAll()
+ {
+ var versionIndependentResourceTypes = Enum
+ .GetNames()
+ .ToHashSet(StringComparer.Ordinal);
+
+ var missingResourceTypes = ModelInfo.SupportedResources
+ .Where(resourceType => !versionIndependentResourceTypes.Contains(resourceType))
+ .OrderBy(resourceType => resourceType)
+ .ToArray();
+
+ Assert.Equal(
+ [
+ "ClinicalAssessment",
+ "DeviceAlert",
+ "InsuranceProduct",
+ "MolecularDefinition",
+ "PersonalRelationship"
+ ],
+ missingResourceTypes);
+ }
+}
diff --git a/Tests/Spark.Engine.R6.Tests/Examples/R6ExampleFileTests.cs b/Tests/Spark.Engine.R6.Tests/Examples/R6ExampleFileTests.cs
new file mode 100644
index 000000000..4257f4edc
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Examples/R6ExampleFileTests.cs
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2026, Incendi
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+using Hl7.Fhir.Model;
+using Hl7.Fhir.Serialization;
+using System;
+using System.IO;
+using Xunit;
+
+namespace Spark.Engine.Tests.Examples;
+
+public class R6ExampleFileTests
+{
+ [Theory]
+ [InlineData("patient-example.json", typeof(Patient), "example")]
+ [InlineData("observation-example-bloodpressure.json", typeof(Observation), "blood-pressure")]
+ [InlineData("medicationrequest0301.json", typeof(MedicationRequest), "medrx0301")]
+ public void CanParseR6JsonExamples(string fileName, Type expectedType, string expectedId)
+ {
+ var json = File.ReadAllText(Path.Combine("Examples", fileName));
+
+ var deserializer = new FhirJsonDeserializer();
+ var resource = deserializer.Deserialize(json);
+
+ Assert.IsType(expectedType, resource);
+ Assert.Equal(expectedId, resource.Id);
+ }
+}
diff --git a/Tests/Spark.Engine.R6.Tests/Examples/appointment-example2doctors.json b/Tests/Spark.Engine.R6.Tests/Examples/appointment-example2doctors.json
new file mode 100644
index 000000000..9a1b9248e
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Examples/appointment-example2doctors.json
@@ -0,0 +1,96 @@
+{
+ "resourceType": "Appointment",
+ "id": "2docs",
+ "text": {
+ "status": "generated",
+ "div": "\u003cdiv xmlns\u003d\"http://www.w3.org/1999/xhtml\"\u003eDiscussion of Peter\u0027s ultrasound results to plan ongoing treatment options\u003c/div\u003e"
+ },
+ "status": "booked",
+ "serviceCategory": [
+ {
+ "coding": [
+ {
+ "system": "http://example.org/service-category",
+ "code": "gp",
+ "display": "General Practice"
+ }
+ ]
+ }
+ ],
+ "serviceType": [
+ {
+ "concept": {
+ "coding": [
+ {
+ "code": "52",
+ "display": "General Discussion"
+ }
+ ]
+ }
+ }
+ ],
+ "specialty": [
+ {
+ "coding": [
+ {
+ "system": "http://snomed.info/sct",
+ "code": "394814009",
+ "display": "General practice (specialty)"
+ }
+ ]
+ }
+ ],
+ "appointmentType": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v2-0276",
+ "code": "FOLLOWUP",
+ "display": "A follow up visit from a previous appointment"
+ }
+ ]
+ },
+ "description": "Discussion about Peter Chalmers ultrasound results",
+ "supportingInformation": [
+ {
+ "reference": "DiagnosticReport/ultrasound"
+ }
+ ],
+ "start": "2013-12-09T09:00:00Z",
+ "end": "2013-12-09T11:00:00Z",
+ "note": [
+ {
+ "text": "Clarify the results of the ultrasound to ensure context of test was correct"
+ }
+ ],
+ "subject": {
+ "reference": "Patient/example",
+ "display": "Peter James Chalmers"
+ },
+ "participant": [
+ {
+ "actor": {
+ "reference": "Practitioner/example",
+ "display": "Dr Adam Careful"
+ },
+ "required": true,
+ "status": "accepted"
+ },
+ {
+ "actor": {
+ "reference": "Practitioner/f202",
+ "display": "Luigi Maas"
+ },
+ "required": true,
+ "status": "accepted"
+ }
+ ],
+ "meta": {
+ "tag": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
+ "code": "HTEST",
+ "display": "test health data"
+ }
+ ]
+ }
+}
diff --git a/Tests/Spark.Engine.R6.Tests/Examples/careplan-example-f201-renal.json b/Tests/Spark.Engine.R6.Tests/Examples/careplan-example-f201-renal.json
new file mode 100644
index 000000000..0f4350ca2
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Examples/careplan-example-f201-renal.json
@@ -0,0 +1,134 @@
+{
+ "resourceType": "CarePlan",
+ "id": "f201",
+ "contained": [
+ {
+ "resourceType": "CareTeam",
+ "id": "careteam",
+ "participant": [
+ {
+ "role": {
+ "coding": [
+ {
+ "system": "http://snomed.info/sct",
+ "code": "425268008",
+ "display": "Review of care plan"
+ }
+ ]
+ },
+ "member": {
+ "reference": "Practitioner/f201",
+ "display": "Dokter Bronsig"
+ }
+ },
+ {
+ "role": {
+ "coding": [
+ {
+ "system": "http://snomed.info/sct",
+ "code": "229774002",
+ "display": "Caregiver occupation"
+ }
+ ]
+ },
+ "member": {
+ "reference": "Practitioner/f204",
+ "display": "Nurse Carla Espinosa"
+ }
+ }
+ ]
+ },
+ {
+ "resourceType": "Goal",
+ "id": "goal",
+ "lifecycleStatus": "completed",
+ "achievementStatus": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/goal-achievement",
+ "code": "achieved",
+ "display": "Achieved"
+ }
+ ],
+ "text": "Achieved"
+ },
+ "description": {
+ "text": "Re-established renal function with at least healthy nutrients."
+ },
+ "subject": {
+ "reference": "Patient/f201",
+ "display": "Roel"
+ }
+ },
+ {
+ "resourceType": "ServiceRequest",
+ "id": "activity",
+ "status": "completed",
+ "intent": "order",
+ "code": {
+ "concept": {
+ "coding": [
+ {
+ "system": "http://snomed.info/sct",
+ "code": "306005",
+ "display": "Echography of kidney"
+ }
+ ]
+ }
+ },
+ "subject": {
+ "reference": "Patient/f201",
+ "display": "Roel"
+ }
+ }
+ ],
+ "status": "draft",
+ "intent": "proposal",
+ "subject": {
+ "reference": "Patient/f201",
+ "display": "Roel"
+ },
+ "period": {
+ "start": "2013-03-11",
+ "end": "2013-03-13"
+ },
+ "careTeam": [
+ {
+ "reference": "#careteam"
+ }
+ ],
+ "addresses": [
+ {
+ "reference": {
+ "reference": "Condition/f204",
+ "display": "Roel\u0027s renal insufficiency"
+ }
+ }
+ ],
+ "goal": [
+ {
+ "reference": "#goal"
+ }
+ ],
+ "activity": [
+ {
+ "plannedActivityReference": {
+ "reference": "NutritionOrder/renaldiet"
+ }
+ },
+ {
+ "plannedActivityReference": {
+ "reference": "#activity"
+ }
+ }
+ ],
+ "meta": {
+ "tag": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
+ "code": "HTEST",
+ "display": "test health data"
+ }
+ ]
+ }
+}
diff --git a/Tests/Spark.Engine.R6.Tests/Examples/medicationrequest0301.json b/Tests/Spark.Engine.R6.Tests/Examples/medicationrequest0301.json
new file mode 100644
index 000000000..3812042fd
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Examples/medicationrequest0301.json
@@ -0,0 +1,205 @@
+{
+ "resourceType": "MedicationRequest",
+ "id": "medrx0301",
+ "contained": [
+ {
+ "resourceType": "Medication",
+ "id": "med0310",
+ "code": {
+ "coding": [
+ {
+ "system": "http://snomed.info/sct",
+ "code": "430127000",
+ "display": "Oxycodone-containing product in oral dose form"
+ }
+ ]
+ }
+ },
+ {
+ "resourceType": "Provenance",
+ "id": "signature",
+ "target": [
+ {
+ "reference": "ServiceRequest/physiotherapy"
+ }
+ ],
+ "recorded": "2017-02-01T17:23:07Z",
+ "agent": [
+ {
+ "role": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationType",
+ "code": "AUT"
+ }
+ ]
+ }
+ ],
+ "who": {
+ "reference": "Practitioner/example",
+ "display": "Dr Adam Careful"
+ }
+ }
+ ],
+ "signature": [
+ {
+ "type": [
+ {
+ "system": "urn:iso-astm:E1762-95:2013",
+ "code": "1.2.840.10065.1.12.1.1",
+ "display": "Author\u0027s Signature"
+ }
+ ],
+ "when": "2017-02-01T17:23:07Z",
+ "who": {
+ "reference": "Practitioner/example",
+ "display": "Dr Adam Careful"
+ },
+ "targetFormat": "application/fhir+xml",
+ "sigFormat": "application/signature+xml",
+ "data": "dGhpcyBibG9iIGlzIHNuaXBwZWQ\u003d"
+ }
+ ]
+ }
+ ],
+ "identifier": [
+ {
+ "use": "official",
+ "system": "http://www.bmc.nl/portal/prescriptions",
+ "value": "12345689"
+ }
+ ],
+ "status": "completed",
+ "statusReason": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-status-reason",
+ "code": "altchoice",
+ "display": "Try another treatment first"
+ }
+ ]
+ },
+ "intent": "order",
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-admin-category",
+ "code": "inpatient",
+ "display": "Inpatient"
+ }
+ ]
+ }
+ ],
+ "medication": {
+ "reference": {
+ "reference": "#med0310"
+ }
+ },
+ "subject": {
+ "reference": "Patient/pat1",
+ "display": "Donald Duck"
+ },
+ "encounter": {
+ "reference": "Encounter/f201",
+ "display": "encounter who leads to this prescription"
+ },
+ "supportingInformation": [
+ {
+ "reference": "Procedure/biopsy"
+ }
+ ],
+ "authoredOn": "2015-01-15",
+ "requester": {
+ "reference": "Practitioner/f007",
+ "display": "Patrick Pump"
+ },
+ "performerType": {
+ "coding": [
+ {
+ "system": "http://snomed.info/sct",
+ "code": "26369006",
+ "display": "Public Health Nurse"
+ }
+ ]
+ },
+ "performer": [
+ {
+ "reference": "Practitioner/f204",
+ "display": "Carla Espinosa"
+ }
+ ],
+ "reason": [
+ {
+ "concept": {
+ "coding": [
+ {
+ "system": "http://snomed.info/sct",
+ "code": "297217002",
+ "display": "Rib Pain (finding)"
+ }
+ ]
+ }
+ }
+ ],
+ "insurance": [
+ {
+ "reference": "Coverage/9876B1"
+ }
+ ],
+ "note": [
+ {
+ "text": "Patient told to take with food"
+ }
+ ],
+ "dispenseRequest": {
+ "validityPeriod": {
+ "start": "2015-01-15",
+ "end": "2016-01-15"
+ },
+ "numberOfRepeatsAllowed": 0,
+ "quantity": {
+ "value": 30,
+ "unit": "TAB",
+ "system": "http://terminology.hl7.org/CodeSystem/v3-orderableDrugForm",
+ "code": "TAB"
+ },
+ "expectedSupplyDuration": {
+ "value": 10,
+ "unit": "days",
+ "system": "http://unitsofmeasure.org",
+ "code": "d"
+ },
+ "dispenser": {
+ "reference": "Organization/2.16.840.1.113883.19.5"
+ }
+ },
+ "substitution": {
+ "allowedBoolean": true,
+ "reason": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
+ "code": "FP",
+ "display": "formulary policy"
+ }
+ ]
+ }
+ },
+ "eventHistory": [
+ {
+ "reference": "#signature",
+ "display": "Author\u0027s Signature"
+ }
+ ],
+ "meta": {
+ "tag": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
+ "code": "HTEST",
+ "display": "test health data"
+ }
+ ]
+ }
+}
diff --git a/Tests/Spark.Engine.R6.Tests/Examples/observation-example-bloodpressure.json b/Tests/Spark.Engine.R6.Tests/Examples/observation-example-bloodpressure.json
new file mode 100644
index 000000000..9990a3d5f
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Examples/observation-example-bloodpressure.json
@@ -0,0 +1,152 @@
+{
+ "resourceType": "Observation",
+ "id": "blood-pressure",
+ "meta": {
+ "profile": [
+ "http://hl7.org/fhir/StructureDefinition/vitalsigns"
+ ],
+ "tag": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
+ "code": "HTEST",
+ "display": "test health data"
+ }
+ ]
+ },
+ "identifier": [
+ {
+ "system": "urn:ietf:rfc:3986",
+ "value": "urn:uuid:187e0c12-8dd2-67e2-99b2-bf273c878281"
+ }
+ ],
+ "basedOn": [
+ {
+ "identifier": {
+ "system": "https://acme.org/identifiers",
+ "value": "1234"
+ }
+ }
+ ],
+ "status": "final",
+ "category": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/observation-category",
+ "code": "vital-signs",
+ "display": "Vital Signs"
+ }
+ ]
+ }
+ ],
+ "code": {
+ "coding": [
+ {
+ "system": "http://loinc.org",
+ "code": "85354-9",
+ "display": "Blood pressure panel with all children optional"
+ }
+ ],
+ "text": "Blood pressure systolic \u0026 diastolic"
+ },
+ "subject": {
+ "reference": "Patient/example"
+ },
+ "effectiveDateTime": "2012-09-17",
+ "performer": [
+ {
+ "reference": "Practitioner/example"
+ }
+ ],
+ "interpretation": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation",
+ "code": "L",
+ "display": "low"
+ }
+ ],
+ "text": "Below low normal"
+ }
+ ],
+ "bodySite": {
+ "coding": [
+ {
+ "system": "http://snomed.info/sct",
+ "code": "368209003",
+ "display": "Right arm"
+ }
+ ]
+ },
+ "component": [
+ {
+ "code": {
+ "coding": [
+ {
+ "system": "http://loinc.org",
+ "code": "8480-6",
+ "display": "Systolic blood pressure"
+ },
+ {
+ "system": "http://snomed.info/sct",
+ "code": "271649006",
+ "display": "Systolic blood pressure"
+ },
+ {
+ "system": "http://acme.org/devices/clinical-codes",
+ "code": "bp-s",
+ "display": "Systolic Blood pressure"
+ }
+ ]
+ },
+ "valueQuantity": {
+ "value": 107,
+ "unit": "mmHg",
+ "system": "http://unitsofmeasure.org",
+ "code": "mm[Hg]"
+ },
+ "interpretation": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation",
+ "code": "N",
+ "display": "normal"
+ }
+ ],
+ "text": "Normal"
+ }
+ ]
+ },
+ {
+ "code": {
+ "coding": [
+ {
+ "system": "http://loinc.org",
+ "code": "8462-4",
+ "display": "Diastolic blood pressure"
+ }
+ ]
+ },
+ "valueQuantity": {
+ "value": 60,
+ "unit": "mmHg",
+ "system": "http://unitsofmeasure.org",
+ "code": "mm[Hg]"
+ },
+ "interpretation": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation",
+ "code": "L",
+ "display": "low"
+ }
+ ],
+ "text": "Below low normal"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Tests/Spark.Engine.R6.Tests/Examples/patient-example.json b/Tests/Spark.Engine.R6.Tests/Examples/patient-example.json
new file mode 100644
index 000000000..6dc873c29
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Examples/patient-example.json
@@ -0,0 +1,189 @@
+{
+ "resourceType": "Patient",
+ "id": "example",
+ "identifier": [
+ {
+ "use": "usual",
+ "type": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
+ "code": "MR"
+ }
+ ]
+ },
+ "system": "urn:oid:1.2.36.146.595.217.0.1",
+ "value": "12345",
+ "period": {
+ "start": "2001-05-06"
+ },
+ "assigner": {
+ "display": "Acme Healthcare"
+ }
+ }
+ ],
+ "active": true,
+ "name": [
+ {
+ "use": "official",
+ "family": "Chalmers",
+ "given": [
+ "Peter",
+ "James"
+ ]
+ },
+ {
+ "use": "usual",
+ "given": [
+ "Jim"
+ ]
+ },
+ {
+ "use": "maiden",
+ "family": "Windsor",
+ "given": [
+ "Peter",
+ "James"
+ ],
+ "period": {
+ "end": "2002"
+ }
+ }
+ ],
+ "telecom": [
+ {
+ "use": "home"
+ },
+ {
+ "system": "phone",
+ "value": "(03) 5555 6473",
+ "use": "work",
+ "rank": 1
+ },
+ {
+ "system": "phone",
+ "value": "(03) 3410 5613",
+ "use": "mobile",
+ "rank": 2
+ },
+ {
+ "system": "phone",
+ "value": "(03) 5555 8834",
+ "use": "old",
+ "period": {
+ "end": "2014"
+ }
+ }
+ ],
+ "gender": "male",
+ "birthDate": "1974-12-25",
+ "_birthDate": {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/patient-birthTime",
+ "valueDateTime": "1974-12-25T14:35:45-05:00"
+ }
+ ]
+ },
+ "deceasedBoolean": false,
+ "address": [
+ {
+ "use": "home",
+ "type": "both",
+ "text": "534 Erewhon St\nPeasantVille, Rainbow, Vic 3999",
+ "line": [
+ "534 Erewhon St"
+ ],
+ "city": "PleasantVille",
+ "district": "Rainbow",
+ "state": "Vic",
+ "postalCode": "3999",
+ "period": {
+ "start": "1974-12-25"
+ }
+ }
+ ],
+ "contact": [
+ {
+ "relationship": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v2-0131",
+ "code": "N"
+ }
+ ]
+ }
+ ],
+ "name": {
+ "family": "du Marché",
+ "_family": {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/humanname-own-prefix",
+ "valueString": "VV"
+ }
+ ]
+ },
+ "given": [
+ "Bénédicte"
+ ]
+ },
+ "additionalName": [
+ {
+ "use": "nickname",
+ "given": [
+ "Béné"
+ ]
+ }
+ ],
+ "telecom": [
+ {
+ "system": "phone",
+ "value": "+33 (237) 998327"
+ }
+ ],
+ "address": {
+ "use": "home",
+ "type": "both",
+ "line": [
+ "534 Erewhon St"
+ ],
+ "city": "PleasantVille",
+ "district": "Rainbow",
+ "state": "Vic",
+ "postalCode": "3999",
+ "period": {
+ "start": "1974-12-25"
+ }
+ },
+ "additionalAddress": [
+ {
+ "use": "work",
+ "line": [
+ "123 Smart St"
+ ],
+ "city": "PleasantVille",
+ "state": "Vic",
+ "postalCode": "3999"
+ }
+ ],
+ "gender": "female",
+ "period": {
+ "start": "2012"
+ }
+ }
+ ],
+ "managingOrganization": {
+ "reference": "Organization/1"
+ },
+ "meta": {
+ "tag": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
+ "code": "HTEST",
+ "display": "test health data"
+ }
+ ]
+ }
+}
diff --git a/Tests/Spark.Engine.R6.Tests/Service/CapabilityStatementServiceTests.Version.cs b/Tests/Spark.Engine.R6.Tests/Service/CapabilityStatementServiceTests.Version.cs
new file mode 100644
index 000000000..59ad71963
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Service/CapabilityStatementServiceTests.Version.cs
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2026, Incendi
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+using Hl7.Fhir.Model;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Spark.Engine.Tests.Service;
+
+public partial class CapabilityStatementServiceTests
+{
+ private bool ContainsPatientResource(string[] resourceTypes)
+ => resourceTypes.Contains("Patient");
+
+ private bool ContainsObservationResource(string[] resourceTypes)
+ => resourceTypes.Contains("Observation");
+
+ private static bool IsPatientResource(CapabilityStatement.ResourceComponent resource)
+ => resource.Type == "Patient";
+
+ private static bool ContainsOperationDefinition(string expected, IDictionary operations)
+ => operations.Any(operation => operation.Key.Contains(expected));
+}
diff --git a/Tests/Spark.Engine.R6.Tests/Service/PatchServiceTests.Version.cs b/Tests/Spark.Engine.R6.Tests/Service/PatchServiceTests.Version.cs
new file mode 100644
index 000000000..da9166a58
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Service/PatchServiceTests.Version.cs
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2026, Incendi
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+using Hl7.Fhir.Model;
+using Hl7.Fhir.Rest;
+using Xunit;
+
+namespace Spark.Engine.Tests;
+
+public partial class PatchServiceTests
+{
+ private static string MedicationRequestReplaceableConceptPath => "MedicationRequest.performerType";
+
+ private static MedicationRequest CreateMedicationRequestWithActiveStatus()
+ => new() { Id = "test", Status = MedicationRequest.MedicationrequestStatus.Active };
+
+ private static void AssertMedicationRequestStatusCompleted(MedicationRequest resource)
+ => Assert.Equal(MedicationRequest.MedicationrequestStatus.Completed, resource.Status);
+
+ private static MedicationRequest CreateMedicationRequestWithReplaceableConcept()
+ => new()
+ {
+ Id = "test",
+ PerformerType = new CodeableConcept
+ {
+ Coding =
+ [
+ new Coding
+ {
+ System = "abc",
+ Code = "123",
+ },
+ ],
+ Text = "test1",
+ },
+ };
+
+ private static CodeableConcept GetMedicationRequestReplaceableConcept(MedicationRequest resource)
+ => resource.PerformerType;
+
+ private static void AddVersionSpecificMedicationRequestPatch(Parameters parameters)
+ => parameters.AddAddPatchParameter("MedicationRequest", "renderedDosageInstruction", new Markdown("Take once daily"));
+
+ private static void AssertVersionSpecificMedicationRequestPatch(MedicationRequest resource)
+ => Assert.Equal("Take once daily", resource.RenderedDosageInstruction);
+
+ private static Markdown CreateAnnotationText(string text) => new(text);
+}
diff --git a/Tests/Spark.Engine.R6.Tests/Spark.Engine.R6.Tests.csproj b/Tests/Spark.Engine.R6.Tests/Spark.Engine.R6.Tests.csproj
new file mode 100644
index 000000000..fd6a0ba76
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/Spark.Engine.R6.Tests.csproj
@@ -0,0 +1,57 @@
+
+
+
+ net8.0;net9.0;net10.0
+ false
+ Spark.Engine.R6.Tests
+ Spark.Engine.Tests
+ Exe
+ $(DefineConstants);R6_TESTS
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
diff --git a/Tests/Spark.Engine.R6.Tests/TestData/R6/patient-example.json b/Tests/Spark.Engine.R6.Tests/TestData/R6/patient-example.json
new file mode 100644
index 000000000..6dc873c29
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/TestData/R6/patient-example.json
@@ -0,0 +1,189 @@
+{
+ "resourceType": "Patient",
+ "id": "example",
+ "identifier": [
+ {
+ "use": "usual",
+ "type": {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
+ "code": "MR"
+ }
+ ]
+ },
+ "system": "urn:oid:1.2.36.146.595.217.0.1",
+ "value": "12345",
+ "period": {
+ "start": "2001-05-06"
+ },
+ "assigner": {
+ "display": "Acme Healthcare"
+ }
+ }
+ ],
+ "active": true,
+ "name": [
+ {
+ "use": "official",
+ "family": "Chalmers",
+ "given": [
+ "Peter",
+ "James"
+ ]
+ },
+ {
+ "use": "usual",
+ "given": [
+ "Jim"
+ ]
+ },
+ {
+ "use": "maiden",
+ "family": "Windsor",
+ "given": [
+ "Peter",
+ "James"
+ ],
+ "period": {
+ "end": "2002"
+ }
+ }
+ ],
+ "telecom": [
+ {
+ "use": "home"
+ },
+ {
+ "system": "phone",
+ "value": "(03) 5555 6473",
+ "use": "work",
+ "rank": 1
+ },
+ {
+ "system": "phone",
+ "value": "(03) 3410 5613",
+ "use": "mobile",
+ "rank": 2
+ },
+ {
+ "system": "phone",
+ "value": "(03) 5555 8834",
+ "use": "old",
+ "period": {
+ "end": "2014"
+ }
+ }
+ ],
+ "gender": "male",
+ "birthDate": "1974-12-25",
+ "_birthDate": {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/patient-birthTime",
+ "valueDateTime": "1974-12-25T14:35:45-05:00"
+ }
+ ]
+ },
+ "deceasedBoolean": false,
+ "address": [
+ {
+ "use": "home",
+ "type": "both",
+ "text": "534 Erewhon St\nPeasantVille, Rainbow, Vic 3999",
+ "line": [
+ "534 Erewhon St"
+ ],
+ "city": "PleasantVille",
+ "district": "Rainbow",
+ "state": "Vic",
+ "postalCode": "3999",
+ "period": {
+ "start": "1974-12-25"
+ }
+ }
+ ],
+ "contact": [
+ {
+ "relationship": [
+ {
+ "coding": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v2-0131",
+ "code": "N"
+ }
+ ]
+ }
+ ],
+ "name": {
+ "family": "du Marché",
+ "_family": {
+ "extension": [
+ {
+ "url": "http://hl7.org/fhir/StructureDefinition/humanname-own-prefix",
+ "valueString": "VV"
+ }
+ ]
+ },
+ "given": [
+ "Bénédicte"
+ ]
+ },
+ "additionalName": [
+ {
+ "use": "nickname",
+ "given": [
+ "Béné"
+ ]
+ }
+ ],
+ "telecom": [
+ {
+ "system": "phone",
+ "value": "+33 (237) 998327"
+ }
+ ],
+ "address": {
+ "use": "home",
+ "type": "both",
+ "line": [
+ "534 Erewhon St"
+ ],
+ "city": "PleasantVille",
+ "district": "Rainbow",
+ "state": "Vic",
+ "postalCode": "3999",
+ "period": {
+ "start": "1974-12-25"
+ }
+ },
+ "additionalAddress": [
+ {
+ "use": "work",
+ "line": [
+ "123 Smart St"
+ ],
+ "city": "PleasantVille",
+ "state": "Vic",
+ "postalCode": "3999"
+ }
+ ],
+ "gender": "female",
+ "period": {
+ "start": "2012"
+ }
+ }
+ ],
+ "managingOrganization": {
+ "reference": "Organization/1"
+ },
+ "meta": {
+ "tag": [
+ {
+ "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
+ "code": "HTEST",
+ "display": "test health data"
+ }
+ ]
+ }
+}
diff --git a/Tests/Spark.Engine.R6.Tests/TestData/R6/patient-example.xml b/Tests/Spark.Engine.R6.Tests/TestData/R6/patient-example.xml
new file mode 100644
index 000000000..f66dd37ae
--- /dev/null
+++ b/Tests/Spark.Engine.R6.Tests/TestData/R6/patient-example.xml
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/Spark.Engine.Tests.Shared/Core/FhirModelTests.cs b/Tests/Spark.Engine.Tests.Shared/Core/FhirModelTests.cs
index 0f6ae015e..8342a0173 100644
--- a/Tests/Spark.Engine.Tests.Shared/Core/FhirModelTests.cs
+++ b/Tests/Spark.Engine.Tests.Shared/Core/FhirModelTests.cs
@@ -43,9 +43,9 @@ public void FindSearchParameters_UsesGeneratedGenericParameterDefinitions()
}
#endif
-#if R5_TESTS
+#if R5_TESTS || R6_TESTS
[Fact]
- public void FindSearchParameters_UsesGeneratedR5GenericParameterDefinitions()
+ public void FindSearchParameters_UsesGeneratedR5OrLaterGenericParameterDefinitions()
{
var genericParameters = _model.FindSearchParameters("Patient")
.Where(parameter => new[] { "_id", "_lastUpdated", "_tag", "_profile", "_security", "_source" }.Contains(parameter.Name))
diff --git a/Tests/Spark.Engine.Tests.Shared/FhirVersion.cs b/Tests/Spark.Engine.Tests.Shared/FhirVersion.cs
index 58da30f98..728d792a5 100644
--- a/Tests/Spark.Engine.Tests.Shared/FhirVersion.cs
+++ b/Tests/Spark.Engine.Tests.Shared/FhirVersion.cs
@@ -23,4 +23,6 @@ public enum FhirVersionMoniker
R4B = 43,
[EnumLiteral(FhirVersionUtility.VERSION_R5)]
R5 = 5,
+ [EnumLiteral(FhirVersionUtility.VERSION_R6)]
+ R6 = 6,
}
diff --git a/Tests/Spark.Engine.Tests.Shared/Utility/FhirVersionUtility.cs b/Tests/Spark.Engine.Tests.Shared/Utility/FhirVersionUtility.cs
index 3bba6991e..486d493ae 100644
--- a/Tests/Spark.Engine.Tests.Shared/Utility/FhirVersionUtility.cs
+++ b/Tests/Spark.Engine.Tests.Shared/Utility/FhirVersionUtility.cs
@@ -18,6 +18,7 @@ internal class FhirVersionUtility
public const string VERSION_R4 = "4.0";
public const string VERSION_R4B = "4.3";
public const string VERSION_R5 = "5.0";
+ public const string VERSION_R6 = "6.0";
public static Dictionary KnownFhirVersions = new Dictionary
{
@@ -27,6 +28,7 @@ internal class FhirVersionUtility
{ FhirVersionMoniker.R4, VERSION_R4 },
{ FhirVersionMoniker.R4B, VERSION_R4B },
{ FhirVersionMoniker.R5, VERSION_R5 },
+ { FhirVersionMoniker.R6, VERSION_R6 },
};
public static FhirVersionMoniker GetFhirVersionMoniker()
diff --git a/Tests/Spark.Web.R6.Tests/Controllers/.gitkeep b/Tests/Spark.Web.R6.Tests/Controllers/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/Tests/Spark.Web.R6.Tests/Models/.gitkeep b/Tests/Spark.Web.R6.Tests/Models/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/Tests/Spark.Web.R6.Tests/Spark.Web.R6.Tests.csproj b/Tests/Spark.Web.R6.Tests/Spark.Web.R6.Tests.csproj
new file mode 100644
index 000000000..e7eb49b6d
--- /dev/null
+++ b/Tests/Spark.Web.R6.Tests/Spark.Web.R6.Tests.csproj
@@ -0,0 +1,46 @@
+
+
+
+ net10.0
+ false
+ Exe
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AssemblyInfo.cs
+
+
+ Controllers\TestController.cs
+
+
+ Models\TestFileDto.cs
+
+
+ Models\TestJsonDto.cs
+
+
+ MultiFormatterSupportTest.cs
+
+
+
+