# Healthcare Claims X12 Processing DSL A Domain-Specific Language (DSL) for healthcare claims validation and X12 processing, implemented in Haskell. ## Overview This project provides a type-safe, composable DSL for defining business rules for healthcare claims validation. It features both an internal DSL (embedded in Haskell) and an external DSL (text-based syntax for business analysts). ## Features - **Type-Safe Internal DSL**: Uses GADTs to ensure rule correctness at compile time - **Business-Friendly External DSL**: SQL-like syntax that non-programmers can read and write - **Comprehensive Validation**: Support for amount checks, diagnosis codes, procedure codes, place of service, and claim types - **Composable Rules**: Combine simple rules into complex validation logic using `AND`, `OR`, and `NOT` - **Full Test Coverage**: Comprehensive test suite using Hspec ## Project Structure ``` claims-x12-dsl/ ├── src/ │ ├── Claims/ │ │ ├── Types.hs # Core domain types and Rule GADT │ │ ├── Interpreter.hs # Rule evaluation engine │ │ ├── Rules.hs # Example business rules │ │ ├── Parser.hs # External DSL parser (Parsec) │ │ └── Parser/ │ │ └── AST.hs # Abstract syntax tree for external DSL │ └── Lib.hs # Main library exports ├── app/ │ └── Main.hs # Example application ├── test/ │ └── Spec.hs # Test suite ├── examples/ │ └── sample-rules.dsl # Example external DSL rules └── package.yaml # Project dependencies ``` ## Getting Started ### Prerequisites You'll need Stack installed. If you don't have it: **macOS:** ```bash curl -sSL https://get.haskellstack.org/ | sh ``` **Linux:** ```bash curl -sSL https://get.haskellstack.org/ | sh ``` **Windows:** Download the installer from [haskellstack.org](https://docs.haskellstack.org/en/stable/install_and_upgrade/) ### Installation 1. **Clone or navigate to the project:** ```bash cd /path/to/claims-x12-dsl ``` 2. **Build the project:** ```bash stack build ``` This will: - Download and install the correct GHC version (9.6.6) if needed - Install all dependencies - Compile the library and executable - First build takes ~60 seconds; subsequent builds are much faster 3. **Verify the build:** ```bash stack test ``` You should see: ``` 22 examples, 0 failures Finished in 0.0036 seconds ``` ### Running the Application **Run the example application:** ```bash stack run ``` This validates a sample $75,000 inpatient claim and displays results: ``` Healthcare Claims X12 Processing DSL ==================================== Validating example claim: Claim ID: "CLM001" Amount: $75000.00 Type: Inpatient Validation Results: ------------------- Rule 1: FAIL - "Review Required: High value claim exceeds $50,000" Rule 2: PASS Rule 3: PASS Rule 4: PASS Rule 5: PASS ``` ### Running Tests **Run all tests:** ```bash stack test ``` **Run tests with detailed output:** ```bash stack test --test-arguments="--format=progress" ``` **Run tests with coverage:** ```bash stack test --coverage ``` ### Interactive Development **Start a REPL (GHCi):** ```bash stack ghci ``` Then you can interactively test the DSL: ```haskell ghci> :load src/Claims/Types.hs ghci> :load src/Claims/Interpreter.hs ghci> import Data.Decimal ghci> import Data.Time -- Create a claim and test rules interactively ``` ## Usage ### Internal DSL (Haskell) ```haskell import Claims.Types import Claims.Interpreter import Data.Decimal (realFracToDecimal) import Data.Time (fromGregorian) -- Define a claim claim = Claim { claimId = "CLM001" , patientId = "PAT12345" , providerId = "PRV98765" , serviceDate = fromGregorian 2025 1 5 , totalAmount = realFracToDecimal 2 75000 , diagnosisCodes = ["I21.0", "I25.10"] , procedureCodes = ["99223", "93000"] , placeOfService = "21" , claimType = Inpatient } -- Define a rule highValueRule :: Rule ValidationResult highValueRule = If (greaterThan 50000) (needsReview "High value claim exceeds $50,000") approve -- Evaluate the rule result = eval claim highValueRule ``` ### External DSL (Business Analyst Syntax) Create a rules file (e.g., `rules.dsl`): ``` RULE HighValueReview DESCRIPTION "Flag high-value claims for manual review" WHEN claim.amount > 50000 THEN REQUIRE_REVIEW "Claim exceeds high-value threshold" END RULE EmergencyRoomValidation DESCRIPTION "Validate ER claims have appropriate diagnoses" WHEN claim.place_of_service = "23" AND NOT (claim.has_diagnosis "S06" OR claim.has_diagnosis "I21") THEN REJECT "Emergency room claim missing emergency diagnosis" END ``` Parse and use the rules: ```haskell import Claims.Parser rulesText <- readFile "rules.dsl" case parseRules rulesText of Left err -> print err Right parsedRules -> do let internalRules = map convertToInternalRule parsedRules let results = validateClaim claim internalRules print results ``` ## Built-in Business Rules The library includes several example business rules: 1. **High Value Claims Review**: Claims exceeding $50,000 require manual review 2. **Emergency Room Validation**: ER claims must have emergency diagnosis codes 3. **Inpatient Admission**: Inpatient claims must include admission procedure codes 4. **Complex Professional Claims**: Multi-condition validation for professional claims 5. **Outpatient Surgery Minimum**: Outpatient surgeries must meet minimum amounts ## External DSL Syntax ### Conditions - Amount comparisons: `claim.amount > 50000`, `claim.amount BETWEEN 0 AND 100` - Code checks: `claim.has_diagnosis "I21"`, `claim.has_procedure "99223"` - Claim properties: `claim.type = "Inpatient"`, `claim.place_of_service = "23"` - Logical operators: `AND`, `OR`, `NOT` ### Actions - `APPROVE`: Automatically approve the claim - `REJECT "message"`: Reject the claim with a reason - `REQUIRE_REVIEW "message"`: Flag for manual review ## Dependencies - **base**: Core Haskell library - **text**: Efficient text handling - **time**: Date/time support - **Decimal**: Precise decimal arithmetic for currency - **parsec**: Parser combinator library for external DSL - **containers**: Data structures - **hspec**: Testing framework - **QuickCheck**: Property-based testing ## License BSD-3-Clause ## Author Based on the Healthcare Claims X12 Processing DSL specification.