Jalen Stephens (js5987) ➡️ Configured database connection
Kira Ariyan (kna2121) ➡️ Configured LLM API connection
Zilin Jing (zj2398) ➡️ Set up PDF parser
Darran Shivdat (dss2194) ➡️ Constructed front end
This directory contains a Ruby on Rails 7 starter application tailored for the AI Appeal Assistant SaaS product. It includes RSpec and Cucumber wiring so you can immediately begin implementing features and acceptance tests.
(Only necessary to test locally)
-
Ensure you have Ruby 3.4.5 installed.
-
Install dependencies:
bundle install
-
To run locally you need to set an environment variable with your openai api key. To avoid this, use the production version of ClearClaim on heroku (linked below).
export OPENAI_API_KEY="your_key"
-
Set up the database (make sure postgresql is running on your machine):
bin/rails db:setup
-
Run the Rails server:
bin/rails server
Troubleshooting note: If you run into DB connection issues ensure your local postgres is configured as follows:
export POSTGRES_USER="postgres"
export POSTGRES_PASSWORD=""
export POSTGRES_HOST="localhost"This is only necessary if it is not already configured this way.
- Accepts EOB documents in PDF format (digital or scanned)
- Handles both machine-readable and image-based PDFs
- OCR-powered PDF parsing for EOB documents using RTesseract
- Extracts patient demographics, billing codes, and denial reasons
- Parses billing line items with service dates and amounts
- Cross-references 1000+ Georgia EOB codes with payer policies
- Maps important denial codes (eg: remit codes and remark codes) to detailed explanations
- Provides actionable correction recommendations for each denial
- Input deidentified patient information to LLM to generates fully formatted, persuasive appeal letters.
- Cites relevant policy language and supporting documentation
- Customizable templates for different payers and denial types
- Addresses each denial code with specific corrections
The production app is deployed on Heroku. You can access the live instance here:
👉link: https://clearclaim-coms4152-c1ad14d4491b.herokuapp.com/
The OpenAI API key is securely stored in Heroku environment variables (OPENAI_API_KEY), so no manual setup is required to test the deployed app.
| Endpoint | Purpose | Required params |
|---|---|---|
POST /claims/analyze |
Ingest a denied-claim PDF/image and return extracted metadata and denial codes. | file (multipart upload) |
POST /claims/suggest_corrections |
Map denial/EOB codes (or [remit_code, remark_code] tuples like ["CO45","N54"]) to stored reasons/corrections. |
denial_codes[] |
POST /claims/generate_appeal |
Produce an appeal draft using claim payload + denial reasons. | claim[...], denial_codes[] |
Example request to analyze a PDF:
curl -X POST http://localhost:3000/claims/analyze \
-F "file=@spec/fixtures/files/sample_denial.pdf"Example correction lookup with tuple payload:
curl -X POST http://localhost:3000/claims/suggest_corrections \
-H "Content-Type: application/json" \
-d '{
"denial_codes": [
["CO29", "N211"],
["PR3", null]
]
}'Example appeal generation:
To test from terminal:
** You must have environment variable $OPENAI_API_KEY set for this to work.
curl -X POST http://localhost:3000/claims/generate_appeal \
-H "Content-Type: application/json" \
-d '{
"claim": {
"claim_number": "12345",
"patient_name": "Jane Doe",
"payer_name": "Clear Health",
"service_period": "Jan 1-5 2024",
"submitter_name": "ClearClaim Assistant"
},
"denial_codes": ["CO45", "PR204"]
}'- Run
bin/rails db:migrateto create thedenial_reasonstable with columns for EOB code (code), payer description, rejection code, group code, parsed reason codes (array), remark code, suggested corrections, and documentation. - Keep the GA EOB crosswalk (or any payer-provided spreadsheet) in
config/EOBList.csv. Seed the table viabin/rails db:seedor manually import withbin/rails denial_reasons:import_eob[/absolute/path/to/EOBList.csv]. - Each row in the CSV must include headers
EOB CODE, DESCRIPTION, Rejection Code, Group Code, Reason Code, Remark Code; multiple reason codes in a single cell (e.g.,"A1, 45 N54") are automatically split into arrays. Claims::CorrectionSuggesteraccepts plain codes (e.g.,"001") or ERA-style tuples. It automatically splits remittance codes like"CO29"intogroup_code: "CO"andreason_code: "29"before querying the database, and also matches on remark codes such as"N211".- Export the curated DB for auditing/sharing with
bin/rails denial_reasons:export_csv[optional/output.csv]. Claims::CorrectionSuggesterconsumes these records, so the REST API immediately reflects any newly imported or edited codes.
Run RSpec:
bundle exec rspecLine Coverage: 92.75% (371 / 400)
Run Cucumber:
bundle exec cucumberLine Coverage: 85.5% (342 / 400)
Cucumber user stories can be found in our features/.feature files.
On the homepage, upload any of the 3 provided sample pdf files which can be found under spec/fixtures/.
Then Analyze Document > Generate Appeal.
You can then download the appeal letter as a .docx and customize it further.
If you upload any invalid document without valid information (like the course syllabus that we showed on demo day), ClearClaim will prompt you to upload another document.
-
Service and repository behaviour for denial lookups lives under
spec/services. Run just those specs with:bundle exec rspec spec/services/claims/correction_suggester_spec.rb spec/services/denial_rules/repository_spec.rb -
Controller behaviour (tuple payloads, JSON responses) is covered by
spec/requests/claims_controller_spec.rb:bundle exec rspec spec/requests/claims_controller_spec.rb -
End-to-end cucumber scenario for ERA tuples is defined in
features/denial_corrections.feature:bundle exec cucumber features/denial_corrections.feature
These tests assume you have migrated and seeded the database (bin/rails db:migrate db:seed) so the denial lookup table exists.