Skip to content

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 with BankValidator.*

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 through IBusinessCriteria, 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>Data envelope + payload class per resource) with no business logic; used to project business objects into REST payloads for cross-application interop.
  • Print (letter generation): clsLetterRequest/clsLetterRequestCollection retrieve and assemble print-ready letter content by calling LegalApi REST endpoints (e.g. v1/Integration/LetterRequests, v1/Integration/WorkerInfo/{id}, v1/Integration/WorkerAtty/{id}) rather than SQL; its IBusinessCriteria implementation always throws InvalidSQLProperty, confirming an API-backed rather than SQL-backed data path — the same behavioral pattern documented for clsBusinessApiCriteriaBase in 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 DataSet for bank/institution data; not hand-authored business logic.*

Interaction model

  • The (out-of-scope) presentation layer invokes public methods/properties on clsBusinessBase-derived entities and clsBusinessCollection-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 named IApiClient resolved via GetApiClient()/FormatRoute().†
  • LegalNet\clsLegalCase.CheckForOtherCases() and the entire Print\ subsystem call out to the LegalApi/integration REST tier (DataPortalInfo.ApiClients("LegalApi"), routes such as v1/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 to SAIF.Services.Exchange for calendar sync (suppressed outside Production via AppGlobal.EnvironmentService.GetApplicationEnvironment()).*
  • mdlCodeTables.vb is 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.Policy library defines both clsMCOCollection and clsPolicyMCOCollection, which independently call the identical stored procedure pk72846_view_policy.getmco with identical parameters, differing only in the item type populated (clsMCO vs. 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.vb and TableMaint\clsOtherFirm.vb each implement an ad-hoc ValidateState() lookup against ALL_STATES/NCCI_STATE_CODE that builds its SQL via raw string concatenation of a user-suppliable State value rather than a bound parameter. This bypasses the standard IBusinessCriteria bind-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 the LegalApi integration 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 IBusinessCriteria implementations inherit clsRetrieveOnlyBusinessCriteria, 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, and clsLegalSchedule each branch on AppGlobal.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:

  • clsBusinessBase owns a clsRulesManager (Rules), supports BeginEdit/CancelEdit/ApplyEdit edit-session management, implements IDataErrorInfo for broken-rule surfacing to data-bound UI controls, and drives Save/Create/Retrieve through the data-portal dispatch path; Save()/SaveChild() throw ApplicationException if 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-level Save()/SaveChild() that persists deferred deletions first, then active children, stopping at the first rule failure.†
  • clsBusinessCollectionBase is the non-generic collection base used by clsLetterRequestCollection, providing the same traversal/error-aggregation surface without a strongly-typed item constraint.†
  • clsRetrieveOnlyBusinessCriteria overrides CreateSQL/InsertSQL/UpdateSQL/DeleteSQL to throw ApplicationException("SQL property not available.") on access, and exposes a protected SetRetrieveSQL(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 41 IBusinessCriteria implementations.†
  • clsBusinessApiCriteriaBase leaves all five SQL properties (RetrieveSql, InsertSql, UpdateSql, DeleteSql, CreateSql) returning the CLR default by design, and instead exposes ApiRoutes, GetApiClient(apiClientKey As String, controller As String), and FormatRoute(routeKey As String) to resolve a named IApiClient and render REST routes — the mechanism this library's clsCaseSearchResult nested criteria and the entire Print\ subsystem rely on (framework BR-004: "API criteria SQL properties are always empty by design").†
  • clsAddress, inherited by clsHearingLocationInfo in this library, is documented at the library level in SAIF.Framework.Core but 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 to clsHearingLocationInfo is 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.

Sources

  • SAIF.Business.Claim.Legal\SAIF.Business.Claim.Legal.vbproj
  • SAIF.Business.Claim.Legal\LegalNet\ (all .vb files)
  • SAIF.Business.Claim.Legal\TableMaint\ (all .vb files)
  • SAIF.Business.Claim.Legal\LegalApi\ (all .vb files)
  • SAIF.Business.Claim.Legal\mdlCodeTables.vb
  • SAIF.Business.Claim.Legal\Web.config, app.config
  • SAIF.Business.View.Policy\SAIF.Business.View.Policy.vbproj (resolved framework types: clsBusinessBase, clsBusinessCollection, clsBusinessCollectionBase, clsRetrieveOnlyBusinessCriteria, clsBusinessApiCriteriaBase, clsAddress — Legends CLI RAG results from SAIF.Framework.Core)