---
title: SAIF.Data architecture
summary: Architectural responsibilities, boundaries, and interaction patterns.
status: draft
owner: SAIF.Core documentation team
last_reviewed: 2026-09-24
library: SAIF.Data
reference_type: package
---

# SAIF.Data architecture

SAIF.Data is the data layer of the `SAIF.SAIFCode.Core` package: it defines roughly 450 NHibernate-mapped entity models, 37 query providers that read them through `IRepositoryFactory`/NHibernate LINQ, two outbound HTTP clients to Guidewire ClaimCenter and the Medical Billing API, an Autofac registration extension for those clients, and a set of in-memory test-data seeding helpers that ship in the production assembly (`saif-data-analysis.md` Architecture findings).

## Responsibilities
- Define the entity and DTO model surface (~461 public types under `SAIF.Data.Model.*`) that `SAIF.Data.NHibernate` maps to Oracle tables; the persistence mappings themselves live outside this library.
- Implement 37 query providers, each deriving from the external `QueryProviderBase`, encapsulating LINQ queries over `Factory.GetRepository<T>().Query()` plus related business logic (`saif-data-analysis.md` Public surface summary).
- Provide two outbound HTTP clients — `MedicalBillingApiService` and `CCClaimApiService` — that call the Medical Billing API and the Guidewire CC Claim Data API respectively, the latter deriving from `SAIF.Data.Guidewire.Clients.HttpClientBase`.
- Register the data API clients, a Polly cache policy, and Microsoft.Extensions Options/MemoryCache infrastructure through `ContainerBuilderExtensions.AddDataClients`, the library's only public Autofac entry point.
- Ship `TestRepository/**` in-memory seeding builders and extensions for test setup, even though they are compiled into the production assembly.

## Component boundaries
- `Model/`: entity and DTO definitions (Claims, Bills, Ebilling, Collections, Legal, Policies, Providers, Documents, OutputDocuments, Tasks, Rct, Agencies, and others); mapped externally by `SAIF.Data.NHibernate`.
- `Queries/`: 37 query providers and their `I*QueryProvider` interfaces, plus `CCClaimApiService`.
- `Clients/`: `HttpClientBase` (local abstract base), `MedicalBillingApiService`, and its interface.
- `Configuration/`: `ContainerBuilderExtensions`, the sole Autofac registration surface.
- `Interfaces/Repositories/`: repository interface groups (Groups, Imaging, OutputDocuments).
- `TestRepository/`: in-memory seeding builders and extensions shipped in the production assembly.

## Interaction model
Consumers such as SAIF.Services, SAIF.Domain, and the Web.Mvc5 front end resolve query providers (registered outside this library, for example in `DependencyMaps/*`) and call them; each provider executes NHibernate LINQ through `IRepositoryFactory`/`IRepository<T>`, whose runtime implementation is supplied by `SAIF.Data.NHibernate` via the external `SAIF.Framework.Data.NHibernate` package. Some providers combine this with calls into `SAIF.Data.Guidewire`'s HTTP clients for hybrid Oracle/Guidewire data sourcing — for example `ClaimQueryProvider` uses `IClaimDataApiClient`/`ICCClaimApiService` for claim, MCO, and financial data, and `LegalQueryProvider.GetClaimIdForCase` calls the CC API before falling back to legacy identifiers (`saif-data-analysis.md` Architecture findings, OP-SD-15, OP-SD-18). `ContainerBuilderExtensions.AddDataClients` is the entry point hosts call to wire up the Guidewire clients, credentials, and the Polly cache policy at startup.

## Architecture diagram
The following diagram shows how consumers reach the entity/query layer, the NHibernate-backed data path, and the Guidewire/Medical Billing HTTP path.

```mermaid
flowchart TD
	Consumers["SAIF.Services / SAIF.Domain /<br>SAIF.Web.Mvc5 callers"] --> QP["37 query providers<br>(QueryProviderBase)"]
	QP --> Repo["IRepositoryFactory /<br>IRepository&lt;T&gt;.Query() (NHibernate LINQ)"]
	Repo --> NH["SAIF.Data.NHibernate<br>ClassMaps and repositories"]
	QP --> CCApi["CCClaimApiService"]
	QP --> MBApi["MedicalBillingApiService"]
	CCApi --> GWBase["SAIF.Data.Guidewire<br>HttpClientBase"]
	MBApi --> LocalBase["SAIF.Data.Clients<br>HttpClientBase"]
	GWBase --> GWAPI["Guidewire ClaimCenter API"]
	LocalBase --> MBAPI["Medical Billing REST API"]
	Config["ContainerBuilderExtensions.AddDataClients"] --> CCApi
	Config --> MBApi
```

## Sequence diagram
The following diagram shows a representative hybrid call: validating and retrieving a claim through the Guidewire CC Claim Data API (OP-SD-04).

```mermaid
sequenceDiagram
	participant Caller as SAIF.Services caller
	participant CCApi as CCClaimApiService
	participant GWBase as Guidewire HttpClientBase
	participant CC as Guidewire ClaimCenter API
	Caller->>CCApi: ValidateClaim(claimId)
	CCApi->>GWBase: GetAsyncCached<T>(GET v1/GeneralClaimData/Claim/{id})
	GWBase->>CC: GET v1/GeneralClaimData/Claim/{id}
	CC-->>GWBase: 200 OK / claim data
	GWBase-->>CCApi: Deserialized response
	CCApi-->>Caller: true/false
```

## Design constraints
- There is no composition root, session, or transaction management in this library; units of work are supplied by external `SAIF.Framework.*` packages (`saif-data-analysis.md` Architecture findings/Boundaries).
- Data sourcing is hybrid: several query providers combine Oracle-backed entity reads with Guidewire REST calls, and several legacy WCIS claim-activity queries now throw `NotImplementedException` with the message "data retired," indicating an in-flight migration ([SD-BR-045 Retired WCIS claim activity queries are unsupported](business-rules.md#sd-br-045-retired-wcis-claim-activity-queries-are-unsupported)).
- Writes performed directly in this library are rare and limited to in-memory entity mutation (`EbillQueryProvider.SetCompoundDrugForAllServiceLinesForTheBill`, [SD-BR-052 Multiple prescription numbers mark all NDC lines as compound drug](business-rules.md#sd-br-052-multiple-prescription-numbers-mark-all-ndc-lines-as-compound-drug), plus model helper methods); persistence is committed by the caller's `IUnitOfWork`.
- `TestRepository/**` seeding helpers are compiled into the production assembly; whether that is intentional is unknown (`saif-data-analysis.md` Open questions item 5)**.
- Query provider registration and lifetimes are decided outside this library, for example in `DependencyMaps/*` (`saif-data-analysis.md` Architecture findings).
- `HttpClientBase.GetAsyncCached` builds its cache key from type, URL, `ensureSuccess`, and body hash only, with no per-user component, so downstream per-user data-level filtering is not reflected in the shared 30-second cache (`saif-data-security-analysis.md` Security concerns, Medium severity)*.
- Credentials are decrypted with `SystemHashUtil` and split on `|` without a length check; a malformed secure setting raises `IndexOutOfRangeException` rather than a descriptive error (`saif-data-config-analysis.md` Secure settings catalog)*.

> **Note:** Statements marked with `*` were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with `**` could not be confirmed; treat as unknown until verified.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Security and authorization](security-authorization.md)
- [Database tables](database-tables.md)
- [SQL catalog](sql/index.md)
- [API reference](api/index.md)

## Sources
- `Data/SAIF.Data/SAIF.Data.csproj`
- `Data/SAIF.Data/Configuration/ContainerBuilderExtensions.cs`
- `Data/SAIF.Data/Clients/HttpClientBase.cs`
- `Data/SAIF.Data/Clients/MedicalBillingApiService.cs`
- `Data/SAIF.Data/Queries/Claims/CCClaimApiService.cs`
- `Data/SAIF.Data/Queries/Claims/ClaimQueryProvider.cs`
- `Data/SAIF.Data/Queries/Legal/LegalQueryProvider.cs`
- `Data/SAIF.Data/Queries/Claims/Ebilling/EbillQueryProvider.cs`
- `Data/SAIF.Data/TestRepository/**`
