Skip to content

SAIF.Services architecture

SAIF.Services is the application/business-service layer of SAIF.Core: a .NET Framework 4.6.2 class library of 227 public types (221 classes, 5 interfaces, 1 enum), excluding generated proxy/designer classes, organized into functional areas (Claims, Legal, Policies/Certificates, Collections, Agencies, Groups, Documents, Investigations, and others) that implement the service contracts declared in SAIF.SAIFCode.Core, orchestrate transactions and authorization, delegate domain logic to SAIF.Domain, persist through SAIF.Data/SAIF.Data.NHibernate, and integrate with external systems such as Guidewire ClaimCenter, OnBase imaging, a PDF merge API, CleanAddress, and email, before returning DTOs (via AutoMapper) to the MVC web host and batch/console callers. (The API reference documents 236 public types — 9 more than this figure — because it additionally includes generated proxy/designer classes not counted here.)

Responsibilities

  • Implement the service interfaces declared in SAIF.SAIFCode.Core (SAIF.Core.Contracts.*), for example BillService : IBillService, EbillingService : IEbillingService, ClaimSecurityService : IClaimSecurityService, PolicySecurityService : IPolicySecurityService, CertificateSecurityService : ICertificateSecurityService, CollectionsService : ICollectionsService, TaskService : ITaskService, LegalTaskService : ILegalTaskService.
  • Orchestrate transactions through IUnitOfWork.Begin()/Commit()/Rollback() around repository and domain calls.
  • Validate input using FluentValidation AbstractValidator<T> classes co-located with their services (for example Claims/Bills/Validators/*, Legal/**/Validators, Claims/Tasks/ClaimTaskValidator), plus IValidationService / SaifValidationException.
  • Enforce authorization programmatically via IUserProfileService.GetCurrentUser()/GetSystemUser()/GetApplicationUser() combined with .IsAuthorized("<resource>"), plus data-level security services (see Design constraints).
  • Map domain/data entities to DTOs using static AutoMapper Mapper.CreateMap configuration (304 call sites) in per-area *MappingHelper classes.
  • Delegate business/domain logic to SAIF.Domain (for example Bill.ModifyStatus/SendPend/Approve, BillRegenerator.Regenerate, EobBuilder.GenerateEobs, File837Extractor.ProcessFile, Claim.GetSecurityAttributes).
  • Integrate with external systems: Guidewire ClaimCenter (IClaimDataApiClient, ICCClaimApiService, IFinancialDataApiClient), OnBase imaging (ImagingClient), a PDF merge API (IPdfClient.Merge), the CleanAddress ASMX service (clsCAServices), email (IEmailService.SendEmail), xPressions batch files, and the file system (EDI in/out, IDM auto-import, PDF data directory).

Component boundaries

  • Claims area (Claims/**, 86 public types) — bills, e-billing/EDI, ICD-10 codes, payments, authority, information, Medicare, severity model, tasks, notes, RTW, security overrides, pharmacy eligibility, and reporting; the largest and most integration-heavy area (Guidewire, OnBase, PDF, EDI files).
  • Legal area (Legal/**, 28 public types) — case/bill/subpoena/note/task services for the legal division, including payment authority checks via EmployeeAuthorityLimit rather than IsAuthorized.
  • Policies/Certificates area (Policies/**, 27 public types) — policy security, certificate lifecycle (renew/resend/edit/delete), policy documents API, DCBS Oregon business reporting.
  • Security components (Security/ClaimSecurityService, Policies/SecurityServices/PolicySecurityService, Policies/Certificates/CertificateSecurityService, plus per-area CanUserEdit/CanUserUpdate members) — own the 66 programmatic authorization-enforcement members identified in saif-services-security-analysis.md*, spanning claim, legal, policy, certificate, collections, agency/group imaging, and system-user access. This is a distinct, cross-cutting component boundary rather than a single class, and is treated as a design constraint below.
  • Collections/misc area (Collections/**, Agencies/**, Groups/**, Documents/**, Imaging/**, Investigations/**, and other smaller folders, 13 + fewer types each) — collections/SOIL processing, agency and group management (including imaging security), document templates/requests, fraud investigations, address verification, and batch processing.
  • Persistence boundary — all data access from this library goes through IUnitOfWork.GetRepository<T>() (SAIF.Data.NHibernate RepositoryBase<T>), SAIF.Data query providers, and SAIF.Data.NHibernate custom repositories; this library declares no ClassMaps, executes no raw SQL/ADO.NET, and holds no connection strings — the one generated PL/SQL script (Documents/TemplateSearchService.GetDocumentSqlLines) is built as text and never executed.
  • Configuration boundary — configuration is read exclusively through IEnvironmentService.GetConfigSetting(key) / IsProduction (SAIF.Framework.Core); there is no ConfigurationManager.AppSettings or DbConnectionManager usage in this library.

Interaction model

  • The MVC web host (Web/SAIF.Web.Mvc5) and batch/console callers construct SAIF.Services classes through constructor injection*; this library performs no DI container registration itself (no ContainerBuilder/RegisterType/Autofac.Module found).
  • Each service method typically begins a unit of work, validates input, checks authorization, calls SAIF.Domain and/or SAIF.Data/SAIF.Data.NHibernate repositories, optionally calls an external system client (Guidewire, OnBase, PDF, CleanAddress, email), maps results with AutoMapper, and commits or rolls back the transaction.
  • Some classes bypass constructor-supplied dependencies and construct query providers directly with new (for example new BillQueryProvider(...) in BillService, new CertificateHolderQueryProvider(...) in CertificateHolderService), which is an internal implementation detail rather than a formal boundary.
  • SAIF.Services consumes, but does not itself expose, a SOAP client boundary: the CleanAddress ASMX proxy (Web References/CleanAddressSvc) is analyzed separately in cleanaddresssvc-analysis.md.

Architecture diagram

The following diagram shows high-level component interactions between the SAIF.Services functional areas, its persistence/domain dependencies, and the external systems it integrates with.

flowchart TD
    Host["MVC web host /<br>batch callers"] --> Claims["Claims services<br>(Bills, EBilling, Tasks, RTW)"]
    Host --> Legal["Legal services<br>(Bills, Subpoenas, Notes)"]
    Host --> Policies["Policies / Certificates<br>services"]
    Host --> Collections["Collections / Agencies /<br>Groups / Documents services"]
    Claims --> Security["Security components<br>(ClaimSecurityService,<br>PolicySecurityService,<br>CertificateSecurityService)"]
    Legal --> Security
    Policies --> Security
    Collections --> Security
    Claims --> Domain["SAIF.Domain"]
    Legal --> Domain
    Policies --> Domain
    Claims --> Data["SAIF.Data /<br>SAIF.Data.NHibernate"]
    Legal --> Data
    Policies --> Data
    Collections --> Data
    Data --> Oracle[("Oracle database")]
    Claims --> Guidewire["Guidewire ClaimCenter"]
    Claims --> OnBase["OnBase imaging"]
    Legal --> OnBase
    Collections --> OnBase
    Claims --> PdfApi["PDF merge API"]
    Collections --> CleanAddress["CleanAddress ASMX"]
    Legal --> Email["Email (IEmailService)"]

Sequence diagram

The following diagram shows a representative bill-processing request/response sequence spanning validation, authorization, persistence, and an external system call.

sequenceDiagram
    participant Client as MVC web host
    participant Service as BillService
    participant Security as ClaimSecurityService
    participant Data as SAIF.Data.NHibernate
    participant Guidewire as Guidewire ClaimCenter
    Client->>Service: Submit bill action
    Service->>Security: GetClaimSecurity(claim, user)
    Security-->>Service: HasConflictAccess / HasSecureAccess
    Service->>Data: IUnitOfWork.Begin(), GetRepository&lt;Bill&gt;().Query()/Update()
    Data-->>Service: Bill entity
    Service->>Guidewire: ICCClaimApiService call (as needed)
    Guidewire-->>Service: Payment/claim data
    Service->>Data: IUnitOfWork.Commit()
    Service-->>Client: Mapped bill DTO

Design constraints

  • Authorization is a load-bearing, cross-cutting boundary. saif-services-security-analysis.md records 102 IsAuthorized invocations grouped into 66 programmatic enforcement members across 0 attribute-based checks, spanning Claims, Legal, Policies/Certificates, Collections, and Agencies/Groups. This library has three confirmed security concerns (SEC-01: bill-entry search returns unfiltered bills despite computing a filtered set; SEC-02: CertificateService.RenewCertificate/ResendCertificate perform no server-side permission check; SEC-03: MCO and medical-provider users can see all non-secure policies). Changes to the security components listed under Component boundaries (ClaimSecurityService, PolicySecurityService, CertificateSecurityService, and the per-area CanUserEdit/CanUserUpdate/IsAuthorized call sites) carry elevated security risk and should be reviewed against saif-services-security-analysis.md before modification.
  • No DI registration ships with this library. Consumers (the MVC host) must supply constructor dependencies and lifetime scopes; there is no ContainerBuilder/Autofac.Module to reference*.
  • Persistence must stay ORM-mediated. This library holds no connection strings and performs no raw SQL/ADO.NET; all reads/writes must go through IUnitOfWork.GetRepository<T>(), SAIF.Data query providers, or SAIF.Data.NHibernate repositories, consistent with saif-services-db-analysis.md.
  • Several services hold mutable or static per-instance state (ClaimAuthorityService._currentUser static, CertificateSecurityService.CurrentCertificate, PolicySecurityService.UserToValidate, Rct/RctXmlService.ReturnValues), which is not thread-safe*; consumers should treat these services as non-reentrant.
  • Several code paths leave a unit-of-work transaction open on early return or exception (for example AuthorizationService.UpdateAuthorization, EbillingService.Create277ResponseFile/Process837File, LegalTaskService.UpdateTask), which constrains safe refactoring of error-handling paths.
  • Configuration must go through IEnvironmentService. No ConfigurationManager.AppSettings or DbConnectionManager usage exists in this library; new settings should follow the same pattern documented in saif-services-config-analysis.md.

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.

Sources

  • Services/SAIF.Services/SAIF.Services.csproj
  • Services/SAIF.Services/Claims/Bills/BillQueryService.cs
  • Services/SAIF.Services/Policies/Certificates/CertificateService.cs
  • Services/SAIF.Services/Policies/SecurityServices/PolicySecurityService.cs
  • Services/SAIF.Services/Claims/Authority/ClaimAuthorityService.cs
  • Services/SAIF.Services/Rct/RctXmlService.cs
  • Services/SAIF.Services/Claims/EBilling/EBillingService.cs
  • Services/SAIF.Services/Legal/Tasks/LegalTaskService.cs