LevelUp.Health.IdentityGraph 0.2.0-rc.1

This is a prerelease version of LevelUp.Health.IdentityGraph.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package LevelUp.Health.IdentityGraph --version 0.2.0-rc.1
                    
NuGet\Install-Package LevelUp.Health.IdentityGraph -Version 0.2.0-rc.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="LevelUp.Health.IdentityGraph" Version="0.2.0-rc.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LevelUp.Health.IdentityGraph" Version="0.2.0-rc.1" />
                    
Directory.Packages.props
<PackageReference Include="LevelUp.Health.IdentityGraph" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add LevelUp.Health.IdentityGraph --version 0.2.0-rc.1
                    
#r "nuget: LevelUp.Health.IdentityGraph, 0.2.0-rc.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package LevelUp.Health.IdentityGraph@0.2.0-rc.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=LevelUp.Health.IdentityGraph&version=0.2.0-rc.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=LevelUp.Health.IdentityGraph&version=0.2.0-rc.1&prerelease
                    
Install as a Cake Tool

LevelUp.Health.IdentityGraph

The .NET twin of the cross-tier identity-graph contract for the LevelUp.Health backend (the asclepius P2 plane, A3 / DR-3). Schema-first lift of Ares' shared/identity contract, paired with the TS adapter @lvlup-sw/health-identity off the same single-source identity-graph.yaml.

The package ships three pieces off the single-source asclepius/identity/identity-graph.yaml:

  • IdentityGraph.gen.cs (committed C# adapter, Task 002). Emitted by identity/scripts/generate.ts and committed under asclepius/identity/generated/; compile-linked into this project (not copied) so the YAML stays the single source and the CI golden check (Task 012) compares the committed file against a fresh emit. A disjoint scalar surface from the TS adapter: IdentityGraphColumns, IdentityGraphInvariants, IdentityMatchPolicy (namespace LevelUp.Health.IdentityGraph.Generated). It deliberately does not emit requiredRolesFor.
  • RoleIdentityRequirements (hand-written, Task 004). The C# counterpart of TS requiredRolesFor, lifted domain-free: the clinical PersonLinkTarget coupling is dropped to plain FHIR resource-type strings. Mirrors the YAML roles: table — practitioner requires [Patient, Practitioner]; every other role falls back to the wildcard [Patient].
  • IdentityPersonLinkResolver (lifted, Task 004). The real IIdentityPersonLinkResolver implementation (lifted from Ares' Aegis.Infrastructure.IdentityPersonLinkResolver), backed by IFhirContext<Person> doing Person?link=Type/id reverse-resolution, fail-safe — no FHIR failure escapes ResolveLinkingPersonIdsAsync as an exception (cancellation excepted, which propagates deliberately, so a cancelled write cannot masquerade as either answer). Fail-safe no longer means fail-quiet. A FHIR failure now yields a failed Result carrying IdentityPersonLinkErrors.Unknown — UNKNOWN, which is not a statement that nothing links the resource — and the caching decorator answers it by widening the eviction to the identity resource-type tags, not by falling back to the narrower own-id tag alone. A success with an empty list is NO MATCH; a success with many names every linking Person.

Fills A2's no-op seam

A2 shipped IIdentityPersonLinkResolver as a deliberate no-op (NoOpIdentityPersonLinkResolver). This package supplies the real implementation so a consuming app can register it to replace the no-op. When registered, A2's FhirServiceCachingDecorator evicts the full identity:{personId} subgraph on identity-resource writes.

This is no longer an additive delivery. Earlier revisions of this package shipped without modifying any A2 package; health-v0.2.0-rc.1 ends that. The port itself is retyped in LevelUp.Health.Fhir — ResolveLinkingPersonIdAsync returning Task<string?> became ResolveLinkingPersonIdsAsync returning Task<Result<IReadOnlyList<string>>> — so LevelUp.Health.Fhir changes with this package rather than staying untouched.

Version floor: take LevelUp.Health.Fhir and LevelUp.Health.IdentityGraph at >= 0.2.0-rc.1, together. The interface lives in Fhir and the implementation lives here, so bumping one and not the other leaves an implementation that no longer satisfies the interface it claims — with no compile error, because each assembly was built against a version where the two agreed. It fails at run time, when the container first constructs the resolver — a TypeLoadException where the implementation no longer satisfies the interface, or a MissingMethodException where a caller reaches for a member that moved. FhirServiceCachingDecorator<T> takes the resolver by constructor, so that is the first request resolving a decorated IFhirService<T>, read or write. LevelUp.Health.Abstractions moves with them, since the port's Result<T> is declared there.

Register it with the supplied extension, which uses Replace so the swap is order-independent (works whether called before or after A2's AddFhirInfrastructure, whose no-op TryAdd would otherwise win):

services.AddFhirInfrastructure(configuration);
services.AddFhirResource<Hl7.Fhir.Model.Person>(); // the IFhirContext<Person> the resolver needs
services.AddIdentityPersonLinkResolver();          // swaps the no-op for the real resolver

Cross-language golden-equal (DR-9)

A characterization test (in the .NET lane) compares the C# consts against the committed TS adapter (identity-graph.gen.ts, read as a text fixture — no Node needed) on the genuinely shared scalar surface only: the matchPolicy values and the link columns. It does not assert agreement on requiredRolesFor (TS-only) or IdentityGraphColumns/Invariants (C#-only).

Build & pack

Inherits the repo-root props: net10.0, MinVer-versioned, SourceLink, Lvlup.Build warnings-as-errors. Packs cleanly (.nupkg + this README + .snupkg) via the existing keyless NuGet path (matches A2).

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0-preview.1 90 8/14/2026
0.2.0-rc.1 2,217 8/20/2026
0.2.0-preview.3 83 8/18/2026
0.2.0-preview.2 87 8/14/2026
0.2.0-preview.1 79 8/14/2026
0.1.0 1,223 7/17/2026
0.1.0-rc.1 146 7/15/2026
0.1.0-preview.2 87 7/10/2026
0.1.0-preview.1 189 6/26/2026