SAIF.Business.Claim.Legal architecture¶
SAIF.Business.Claim.Legal is the largest and most central business/domain library in this application, comprising 58 .vb files and 96 framework-derived classes across four functional areas: the legal-case aggregate (LegalNet\), attorney/reference-data maintenance (TableMaint\), a REST DTO surface (LegalApi\), and print/letter generation (Print\). It sits in the BOF "Business Component" tier between the (out-of-scope) presentation layer and the Oracle database, and additionally acts as a REST client/DTO producer for a separate legal/claim API integration tier.
Responsibilities¶
- Model and persist the legal-case aggregate and its lifecycle sub-entities: case header, status history, appeals/board actions, case cost/outcomes, hearings/schedules, mail dates, consolidations, acknowledgements, file locations, and case notes (
LegalNet\). - Maintain attorney/firm/legal-person reference and assignment data largely independent of the case aggregate (
TableMaint\): attorney profiles, conflicts, policy assignments, schedules, hearing locations, other firms, legal persons, and rotation assignments. - Project internal business objects into REST request/response DTO shapes for a legal/claim integration API (
LegalApi\), and provide a print/letter-generation subsystem that assembles print-ready content from both local business objects and REST calls (Print\). - Supply cross-cutting static code-table/lookup access (
mdlCodeTables.vb) consumed across most of the above domains for dropdown/code-table data. - Carry auto-generated typed-DataSet scaffolding (
Institutions.Designer.vb) for bank/institution reference data used withBankValidator.*
Component boundaries¶
- LegalNet (legal-case aggregate): owns the case header (
clsLegalCase) and its dependent sub-entities (status history, appeals, case cost/outcomes, hearings/schedules, mail dates, consolidations, acknowledgements, file locations, notes, evaluations). Persists primarily via Oracle stored procedures/inline SQL throughIBusinessCriteria, with one confirmed hybrid path to a REST API client (clsLegalCase.CheckForOtherCases()). - TableMaint (reference/master data): attorney, firm, hearing-location, legal-person, and assignment/rotation maintenance entities; mostly simple CRUD with
AddBusinessRules()validation, connected to the case aggregate only through foreign-key-style lookups rather than direct object composition. - LegalApi (DTO/API surface): plain data-transfer classes (
<Entity>Dataenvelope + payload class per resource) with no business logic; used to project business objects into REST payloads for cross-application interop. - Print (letter generation):
clsLetterRequest/clsLetterRequestCollectionretrieve and assemble print-ready letter content by callingLegalApiREST endpoints (e.g.v1/Integration/LetterRequests,v1/Integration/WorkerInfo/{id},v1/Integration/WorkerAtty/{id}) rather than SQL; itsIBusinessCriteriaimplementation always throwsInvalidSQLProperty, confirming an API-backed rather than SQL-backed data path — the same behavioral pattern documented forclsBusinessApiCriteriaBasein the framework's own documentation.† - mdlCodeTables (cross-cutting lookups): a static module used by most domains above for code-table/dropdown data; not owned by any single aggregate.
- Institutions.Designer.vb (scaffolding): auto-generated typed
DataSetfor bank/institution data; not hand-authored business logic.*
Interaction model¶
- The (out-of-scope) presentation layer invokes public methods/properties on
clsBusinessBase-derived entities andclsBusinessCollection-derived collections; these dispatch through the inherited framework data-portal path (SAIF.Framework.Core†) to Oracle stored procedures/inline SQL (Pk80001_Legalnet.*,Pk80005_assignment.*) or, for API-backed objects, to a namedIApiClientresolved viaGetApiClient()/FormatRoute().† LegalNet\clsLegalCase.CheckForOtherCases()and the entirePrint\subsystem call out to theLegalApi/integration REST tier (DataPortalInfo.ApiClients("LegalApi"), routes such asv1/integration/LetterRequests,v1/integration/WorkerInfo/{id},v1/integration/WorkerAtty/{id}) — a hybrid SQL + REST data-access pattern inside a single library.*TableMaint\clsAttorneySchedule.Save()/OnSave()directly orchestrates an external service integration, pushing schedule entries toSAIF.Services.Exchangefor calendar sync (suppressed outside Production viaAppGlobal.EnvironmentService.GetApplicationEnvironment()).*mdlCodeTables.vbis called synchronously by most domain entities to populate lookup/dropdown data; it is a shared, stateless cross-cutting dependency rather than part of any aggregate's interaction chain.
Design constraints¶
- Duplicate MCO collection classes across libraries: the sibling
SAIF.Business.View.Policylibrary defines bothclsMCOCollectionandclsPolicyMCOCollection, which independently call the identical stored procedurepk72846_view_policy.getmcowith identical parameters, differing only in the item type populated (clsMCOvs.clsPolicyMCO). This is legacy duplicate code consumed indirectly by this library's policy-lookup dependency chain and is flagged as technical debt rather than a documentation error.* - Non-parameterized
ValidateState()SQL — injection risk:TableMaint\clsHearingLocation.vbandTableMaint\clsOtherFirm.vbeach implement an ad-hocValidateState()lookup againstALL_STATES/NCCI_STATE_CODEthat builds its SQL via raw string concatenation of a user-suppliableStatevalue rather than a bound parameter. This bypasses the standardIBusinessCriteriabind-variable pattern used elsewhere in this library and is a confirmed SQL-injection surface flagged for remediation (see Stage 1b DB analysis, DB-CLL-063/DB-CLL-064). - Hybrid SQL + REST data access within single aggregates: several entities (
clsLegalCase,clsLetterRequest(Collection)) mix Oracle SQL persistence with REST calls to theLegalApiintegration tier, increasing the number of failure/consistency modes a caller must reason about.* - Retrieve-only and API-backed criteria as design guards: 15 of 41
IBusinessCriteriaimplementations inheritclsRetrieveOnlyBusinessCriteria, which throws on any mutating SQL property access, enforcing read-only collection retrieval at the framework level rather than by convention.† - Environment-gated behavior:
clsAttorneySchedule,clsConsolidations, andclsLegalScheduleeach branch onAppGlobal.EnvironmentService.GetApplicationEnvironment()to suppress non-Production side effects (e.g., Exchange calendar sync), meaning behavior differs between environments in ways not fully traceable from local source alone.*
Architecture diagram¶
The diagram groups the library's 96 framework-derived classes into their functional sub-component clusters and shows their relationship to the framework base classes, the Oracle database, and the external REST/service integrations.
flowchart TD
subgraph LegalCaseCore["Legal case core (LegalNet)"]
LC[clsLegalCase /<br>clsLegalCaseCollection]
CSH[clsCaseStatusHistory]
FC[clsFindCase /<br>clsCaseSearchCriteria /<br>clsCaseSearchResult]
end
subgraph AppealsOutcomes["Appeals, board actions & outcomes"]
AP[clsAppeal /<br>clsAppealExtension /<br>clsBoardRecord]
CC[clsCaseCost]
CO[clsCaseOutcome /<br>clsOutcomeIssue /<br>clsOutcomeStaff]
end
subgraph HearingsSchedule["Hearings, schedule & assignment"]
HS[clsLegalSchedule /<br>clsHearingLocationInfo /<br>clsQuickCal]
ASGN[clsAssignmentProcess /<br>clsAssignmentResult]
end
subgraph CaseAdmin["Case notes, mail, consolidation & acknowledge"]
ACK[clsAcknowledge]
CN[clsCaseNote /<br>clsMailDate /<br>clsConsolidations]
RQ[clsRequestIssue /<br>clsLegalFileLocation /<br>clsOtherLegalParty]
end
subgraph TableMaint["Attorney / firm / person maintenance (TableMaint)"]
ATT[clsAttorneyProfile /<br>clsAttorneyConflict /<br>clsAttorneyPolicyAssignment]
LP[clsLegalPerson /<br>clsLegalPersonType /<br>clsOtherFirm]
SCH[clsAttorneySchedule /<br>clsOutOFTownRotationAssgn]
HL[clsHearingLocation]
end
subgraph LegalApiDTO["LegalApi (REST DTOs)"]
DTO[Acknowledgement / FindCase /<br>BoardLog / WorkerAtty / etc.]
end
subgraph PrintLetters["Print (letter generation)"]
PR[clsLetterRequest /<br>clsLetterRequestCollection]
end
CT[mdlCodeTables<br>code-table lookups]
INST[Institutions.Designer.vb<br>typed DataSet]
FWBASE["SAIF.Framework.Core:<br>clsBusinessBase, clsBusinessCollection,<br>clsBusinessCollectionBase,<br>clsRetrieveOnlyBusinessCriteria,<br>clsBusinessApiCriteriaBase, clsAddress"]
ORACLE[(Oracle database<br>Pk80001_Legalnet / Pk80005_assignment)]
LEGALAPI[LegalApi / integration<br>REST tier]
EXCHANGE[SAIF.Services.Exchange]
POLICY[SAIF.Business.View.Policy]
FWBASE --> LegalCaseCore
FWBASE --> AppealsOutcomes
FWBASE --> HearingsSchedule
FWBASE --> CaseAdmin
FWBASE --> TableMaint
FWBASE --> PrintLetters
LegalCaseCore --> ORACLE
AppealsOutcomes --> ORACLE
HearingsSchedule --> ORACLE
CaseAdmin --> ORACLE
TableMaint --> ORACLE
LegalCaseCore -->|CheckForOtherCases| LEGALAPI
PrintLetters -->|v1/integration/*| LEGALAPI
LegalApiDTO -.->|serializes| LegalCaseCore
LegalApiDTO -.->|serializes| PrintLetters
SCH -->|calendar sync| EXCHANGE
ATT -->|policy validity check| POLICY
CT -.-> TableMaint
CT -.-> LegalCaseCore
CT -.-> AppealsOutcomes
Sequence diagram¶
The following diagram illustrates the representative core workflow of creating/updating a legal case, including its optional cross-tier delegation to the LegalApi REST integration.
sequenceDiagram
participant Caller as Presentation caller
participant LC as clsLegalCase
participant Rules as clsRulesManager (Rules)
participant Base as clsBusinessBase (framework)
participant Portal as Data portal
participant Oracle as Oracle (Pk80001_Legalnet)
participant API as LegalApi REST tier
Caller->>LC: Set properties (CaseTypeCode, RequestTypeCode, WcbNum, and other case fields)
LC->>LC: MarkDirty()
Caller->>LC: Save()
LC->>Base: IsValid()
Base->>Rules: CheckRules(businessObject)
Rules-->>Base: broken-rule state
Base->>Base: BeforeInsert / BeforeUpdate
Base->>Portal: ProcessPortalRequest(InsertSQL/UpdateSQL)
Portal->>Oracle: Pk80001_Legalnet.InsertLegalCase / UpdateLegalCase
Oracle-->>Portal: RowsAffected
Portal-->>Base: result
Base->>Base: AfterInsert / AfterUpdate (check RowsAffected = 1)
alt RowsAffected <> 1
Base->>LC: AddErrorMessage("UpdateError","Update Failed")
end
LC->>API: CheckForOtherCases() (optional)
API-->>LC: other-cases result
LC-->>Caller: save result / broken rules
Inherited framework behavior¶
The following statements describe base-class behavior inherited from SAIF.Framework.Core, retrieved from that library's own documentation via the Legends CLI RAG service:
clsBusinessBaseowns aclsRulesManager(Rules), supportsBeginEdit/CancelEdit/ApplyEditedit-session management, implementsIDataErrorInfofor broken-rule surfacing to data-bound UI controls, and drives Save/Create/Retrieve through the data-portal dispatch path;Save()/SaveChild()throwApplicationExceptionif the target is read-only, in the wrong root/child role, still inside an edit level, or invalid after rule evaluation.†clsBusinessCollection(Of T)adds traversal members (First/Next/Last/Previous,CurrentItem,IndexOf) and collection-levelSave()/SaveChild()that persists deferred deletions first, then active children, stopping at the first rule failure.†clsBusinessCollectionBaseis the non-generic collection base used byclsLetterRequestCollection, providing the same traversal/error-aggregation surface without a strongly-typed item constraint.†clsRetrieveOnlyBusinessCriteriaoverridesCreateSQL/InsertSQL/UpdateSQL/DeleteSQLto throwApplicationException("SQL property not available.")on access, and exposes a protectedSetRetrieveSQL(sql As String)as the only supported way to populate retrieval SQL — enforcing the "retrieve-only criteria SQL suppression" rule (framework BR-003) used by 15 of this library's 41IBusinessCriteriaimplementations.†clsBusinessApiCriteriaBaseleaves all five SQL properties (RetrieveSql,InsertSql,UpdateSql,DeleteSql,CreateSql) returning the CLR default by design, and instead exposesApiRoutes,GetApiClient(apiClientKey As String, controller As String), andFormatRoute(routeKey As String)to resolve a namedIApiClientand render REST routes — the mechanism this library'sclsCaseSearchResultnested criteria and the entirePrint\subsystem rely on (framework BR-004: "API criteria SQL properties are always empty by design").†clsAddress, inherited byclsHearingLocationInfoin this library, is documented at the library level inSAIF.Framework.Corebut the RAG service returned no class-specific member/behavior detail for it beyond its presence in the framework's address/business-object model — its structured postal-address contribution toclsHearingLocationInfois inferred from usage rather than confirmed from framework documentation.**
Note: Statements marked with
†are derived from dependency library documentation via the Legends CLI. Statements marked with*were inferred from code structure or contextual evidence. Statements marked with**could not be confirmed; treat as unknown until verified.
Related documentation¶
- Index
- Overview
- Dependencies
- Operations and processes
- Business rules
- Database tables
- SQL catalog
- Configuration
- API reference
Sources¶
SAIF.Business.Claim.Legal\SAIF.Business.Claim.Legal.vbprojSAIF.Business.Claim.Legal\LegalNet\(all.vbfiles)SAIF.Business.Claim.Legal\TableMaint\(all.vbfiles)SAIF.Business.Claim.Legal\LegalApi\(all.vbfiles)SAIF.Business.Claim.Legal\mdlCodeTables.vbSAIF.Business.Claim.Legal\Web.config,app.configSAIF.Business.View.Policy\SAIF.Business.View.Policy.vbproj(resolved framework types:clsBusinessBase,clsBusinessCollection,clsBusinessCollectionBase,clsRetrieveOnlyBusinessCriteria,clsBusinessApiCriteriaBase,clsAddress— Legends CLI RAG results fromSAIF.Framework.Core)