# SearchClaimsBySystemFieldString - Advanced Documentation ## Search Strategy Claim Name is auto-generated: non-alphanumeric characters are removed from each part, parts are joined by underscores, and each part is truncated. A person claimant named `FirstName LastName` produces `LastNa_FirstN_{TypeAbbrev6}_{ClaimID}` (last name truncated to first 6 characters, first name truncated to first 6 characters, suffix truncated to first 4 characters when present). A company claimant named `Company Name` produces `CompanyName_{TypeAbbrev6}_{ClaimID}` (company name truncated to first 16 characters). Because each part is truncated, never search with a full name. Use short per-part prefixes with wildcards instead: `Las%Fir%` finds person `FirstName LastName`, `Com%Nam%` finds company `Company Name`. Lengthen the prefixes to narrow results when you hit the 50-result cap or get ambiguous matches. ## Cross-Reference Patterns When a user mentions both a case name and a person, combine searches in parallel to find the connection: ```javascript async () => { // Parallel: find the case AND the person's claims at the same time // Claim name starts with a truncated last-name prefix - search by that prefix const [claims, contacts] = await Promise.all([ SecureApi.SearchClaimsBySystemFieldString("Name", "Zippy"), SecureApi.SearchContactsByContactNameAndAKA("bob tig") ]); // Iterate ALL contacts - multiple people may share a name const allContactClaims = []; for (const contact of contacts) { const relatedClaims = await SecureApi.GetRelatedClaims(contact.ID); allContactClaims.push(...relatedClaims.map(rc => ({ contactId: contact.ID, contactName: contact.Name, claimId: rc.Claim.ID, claimName: rc.Claim.Name, claimType: rc.Claim.Type.Name, status: rc.Claim.Status, role: rc.ContactType.Name }))); } // Find overlap: which claims match BOTH the case name and a contact const claimIds = new Set(claims.map(c => c.ID)); const matches = allContactClaims.filter(rc => claimIds.has(rc.claimId)); return { allClaims: claims.map(c => ({ id: c.ID, name: c.Name })), matches }; } ``` **Key points:** - Use `Promise.all` to run independent searches in parallel - `GetRelatedClaims(contactId)` returns all claims a contact is associated with, including their role - Cross-reference by claim ID to find the connection - One claimant may have multiple claims (e.g., AA, WC, PI) - return all matches and let the caller choose - Always iterate all contacts - never use `contacts[0]` without checking the rest ## Overview Searches claims by matching a caller-selected system field against a string value using prefix matching by default. When searching by the 'Name' field, matches against the auto-generated claim name. This document also covers the broader claim search ecosystem and when to use each endpoint. ## Which Endpoint to Use | Scenario | Endpoint | Notes | |----------|----------|-------| | Have a ClaimID already | `GetClaim` | Direct lookup via spGetClaimFull, no searching needed | | Search by claimant name or claim name | `SearchClaimsExtended` | Searches both fields with OR logic | | Search by a specific system field | `SearchClaimsBySystemFieldString` | Pass the field display name | | Search by a system date field | `SearchClaimsBySystemFieldDate` | Exact day match | | Search by alternate reference number | `SearchClaimsByAlternateReferenceNumber` | Stored procedure search | | Search by claim request reference | `SearchClaimsByClaimRequestReferenceNumber` | Stored procedure search | | Search by contact ad-hoc field | `SearchClaimsByContactTypeAdhocField` | Requires AdHocFieldDefinitionID | | Search by claim ad-hoc field | `SearchClaimsByClaimTypeAdhocField` | Requires AdHocFieldDefinitionID | | Browse/manage saved searches | `GetFirmAdvancedSearches` | Returns both claim and contact saved searches | | Run a saved search | `GetAdvancedSearchResults` | Executes a saved advanced search query | ## Claim Name Format Claim names are auto-generated by `GenerateClaimName` and follow this pattern: ``` {ClaimantName}_{ClaimTypeAbbreviation}_{ClaimID} ``` **For person claimants:** - Format: `{Last6}{First6}{Suffix4}_{TypeAbbrev6}_{ID}` - A claimant named `FirstName LastName` produces `LastNa_FirstN_{TypeAbbrev6}_{ClaimID}` - LastName truncated to first 6 chars, FirstName to first 6 chars, Suffix to first 4 chars (only when present) - Only non-empty parts are joined **For company claimants:** - Format: `{CompanyName16}_{TypeAbbrev6}_{ID}` - A claimant named `Company Name` produces `CompanyName_{TypeAbbrev6}_{ClaimID}` - Company name truncated to first 16 chars **Character rules:** - All non-alphanumeric characters are stripped (regex `[^a-zA-Z0-9]+`) - Only letters (a-z, A-Z) and digits (0-9) survive - Spaces, hyphens, apostrophes, etc. are removed ## Wildcard Matching All text-based claim searches use SQL `LIKE` with prefix matching by default: ```sql WHERE fieldName LIKE @Filter + '%' ``` Callers can include `%` wildcards in the filter for flexible matching: | Filter | SQL Becomes | Matches | |--------|-------------|---------| | `Smith` | `LIKE 'Smith%'` | Claims starting with "Smith" | | `%Smith` | `LIKE '%Smith%'` | Claims containing "Smith" anywhere | | `%Smith%` | `LIKE '%Smith%%'` | Same as above (redundant trailing %) | | `%_PI_` | `LIKE '%_PI_%'` | Claims with "_PI_" in the name (all PI claim types) | | `%_1234` | `LIKE '%_1234%'` | Claims ending with ID 1234 | ## Searchable Claim System Fields ### String Fields (SearchClaimsBySystemFieldString) | Field Display Name | What It Searches | |-------------------|-----------------| | Name | Auto-generated claim name (see format above) | | Details | Claim details text | | Synopsis | Claim synopsis | | Intake Notes | Notes entered during intake | | Alternate Reference Number | External reference number | | Closed Note | Note recorded when claim was closed | | Referred To | Who the claim was referred to | | Referred By | Who referred the claim | | How Did You Hear About Us | Marketing source | | Rank | Claim ranking/priority value | ### Date Fields (SearchClaimsBySystemFieldDate) | Field Display Name | What It Searches | |-------------------|-----------------| | Created Date | When the claim was created | | Incident Date | Date of the incident | | Closed Date | When the claim was closed | | Contract Date | Contract date | | MMI | Maximum Medical Improvement date | | Statute Of Limitations | Statute of limitations date | | Call Date | Date of initial call | | Estimated Value | Estimated claim value (treated as date field) | **Note:** Date searches match the entire day (BETWEEN midnight and just before midnight the next day). ## SearchClaimsExtended Behavior This is the most commonly used search endpoint. Key details: - Searches **both** `c.Name` (claim name) **and** `c.ClaimantIDName` (claimant display name) with OR logic - If the filter parses as a date with year > 1900, it switches to incident date matching instead - Limited to **10 results** (use SearchClaimsBySystemFieldString for up to 50) - Does **not** include closed claims - Results filtered by caller's claim security access ## Security All claim search endpoints enforce: - User must be logged in - User must have a company selected - User must be a member of that company - Results are filtered by claim security (private claims excluded unless user has explicit access) ## Disambiguating "Firm X, case Y" phrasing When a request names two entities ("the `` case in the `` firm"), resolve them independently and in this order: (1) `ResolveCompany(B)` for the firm/company that contains the data for the request, sanity-check the returned `Name` actually resembles `B`; (2) `SearchClaimsBySystemFieldString("Name", A-prefix)` scoped to that company id for the claim. Never assume `A` is a company just because `ResolveCompany(A)` returned a result - validate the name.