> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rcintell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Local testing guide

> Set up the platform from scratch, seed data, and test every API endpoint — macOS, Linux, and Windows

This guide walks you through running the RCI Platform locally, seeding it with CMS sample data, and verifying every API endpoint works. Follow the section for your operating system.

## Prerequisites

| Requirement        | Version | Notes                                                   |
| ------------------ | ------- | ------------------------------------------------------- |
| **Python**         | 3.11+   | 3.12 recommended                                        |
| **Docker**         | 20.10+  | Docker Desktop (macOS/Windows) or Docker Engine (Linux) |
| **Docker Compose** | v2+     | Included with Docker Desktop                            |
| **Git**            | 2.30+   |                                                         |
| **curl**           | any     | Included on macOS/Linux; available on Windows 10+       |

***

## 1. Clone and install

<Tabs>
  <Tab title="macOS">
    ```bash theme={null}
    # Install prerequisites (if needed)
    brew install python@3.12 git

    # Clone and enter the repo
    git clone https://github.com/RCI-Healthcare-knowledbase/rc-platfom.git
    cd rc-platfom

    # Create virtual environment
    python3 -m venv .venv
    source .venv/bin/activate

    # Install the platform with dev dependencies
    pip install -e ".[dev]"

    # Copy environment config
    cp .env.example .env
    ```
  </Tab>

  <Tab title="Linux (Ubuntu/Debian)">
    ```bash theme={null}
    # Install prerequisites
    sudo apt update
    sudo apt install -y python3.12 python3.12-venv python3-pip git curl

    # Install Docker Engine (if not already installed)
    curl -fsSL https://get.docker.com | sh
    sudo usermod -aG docker $USER
    # Log out and back in for the group change to take effect

    # Clone and enter the repo
    git clone https://github.com/RCI-Healthcare-knowledbase/rc-platfom.git
    cd rc-platfom

    # Create virtual environment
    python3 -m venv .venv
    source .venv/bin/activate

    # Install the platform with dev dependencies
    pip install -e ".[dev]"

    # Copy environment config
    cp .env.example .env
    ```
  </Tab>

  <Tab title="Windows (PowerShell)">
    ```powershell theme={null}
    # Install prerequisites:
    #   Python 3.12+ — https://python.org (check "Add to PATH" during install)
    #   Docker Desktop — https://docker.com/products/docker-desktop
    #   Git — https://git-scm.com

    # Clone and enter the repo
    git clone https://github.com/RCI-Healthcare-knowledbase/rc-platfom.git
    cd rc-platfom

    # Create virtual environment
    python -m venv .venv
    .venv\Scripts\activate

    # Install the platform with dev dependencies
    pip install -e ".[dev]"

    # Copy environment config
    copy .env.example .env
    ```

    <Note>
      If `pip install` fails with "Microsoft Visual C++ required", install the [Build Tools for Visual Studio](https://visualstudio.microsoft.com/visual-cpp-build-tools/) (select "Desktop development with C++").
    </Note>
  </Tab>
</Tabs>

***

## 2. Start infrastructure

Start PostgreSQL and Redis with Docker Compose. This is the same on all platforms.

<Tabs>
  <Tab title="macOS / Linux">
    ```bash theme={null}
    # Start the full stack (PostgreSQL + Redis + API + Prometheus + Grafana)
    docker compose up -d

    # Or start only the database and cache (run API locally with hot-reload)
    docker compose up -d postgres redis
    ```
  </Tab>

  <Tab title="Windows (PowerShell)">
    ```powershell theme={null}
    # Make sure Docker Desktop is running first

    # Start the full stack
    docker compose up -d

    # Or start only the database and cache
    docker compose up -d postgres redis
    ```
  </Tab>
</Tabs>

Wait for containers to be healthy:

```bash theme={null}
docker compose ps
```

You should see both `postgres` and `redis` with status **healthy**.

***

## 3. Apply database migrations

```bash theme={null}
alembic upgrade head
```

Expected output:

```
INFO  Running upgrade  -> 001, Initial schema
INFO  Running upgrade 001 -> 002, Structured payer, service code, and prior auth tables
...
INFO  Running upgrade 009 -> 010, Add NCCI summary agent types to agenttype enum
```

All 10 migrations should apply cleanly. If you hit enum errors on a re-run, see the [Troubleshooting](#troubleshooting) section.

***

## 4. Start the API server

<Tabs>
  <Tab title="macOS / Linux">
    If you started the full Docker stack in step 2, the API is already running at `http://localhost:8000`. Skip to step 5.

    To run with hot-reload for development:

    ```bash theme={null}
    uvicorn kustode_platform.main:app --reload --port 8000
    ```
  </Tab>

  <Tab title="Windows (PowerShell)">
    If you started the full Docker stack in step 2, the API is already running at `http://localhost:8000`. Skip to step 5.

    To run with hot-reload for development:

    ```powershell theme={null}
    python -m uvicorn kustode_platform.main:app --reload --port 8000
    ```

    <Note>
      Use `python -m uvicorn` on Windows if `uvicorn` alone is not found in your PATH.
    </Note>
  </Tab>
</Tabs>

***

## 5. Verify the server

<Tabs>
  <Tab title="macOS / Linux">
    ```bash theme={null}
    curl http://localhost:8000/health
    ```
  </Tab>

  <Tab title="Windows (PowerShell)">
    ```powershell theme={null}
    Invoke-RestMethod http://localhost:8000/health
    ```

    Or with curl (available on Windows 10+):

    ```powershell theme={null}
    curl.exe http://localhost:8000/health
    ```

    <Warning>
      PowerShell aliases `curl` to `Invoke-WebRequest`. Use `curl.exe` to call the real curl, or use `Invoke-RestMethod` for cleaner output.
    </Warning>
  </Tab>
</Tabs>

Expected: `{"status":"ok"}`

***

## 6. Bootstrap a tenant and API key

<Tabs>
  <Tab title="macOS / Linux">
    ```bash theme={null}
    curl -X POST http://localhost:8000/v1/admin/bootstrap \
      -H "Content-Type: application/json" \
      -d '{"name": "Test Hospital", "slug": "test-hospital"}'
    ```
  </Tab>

  <Tab title="Windows (PowerShell)">
    ```powershell theme={null}
    $body = '{"name": "Test Hospital", "slug": "test-hospital"}'
    Invoke-RestMethod -Method Post -Uri http://localhost:8000/v1/admin/bootstrap `
      -ContentType "application/json" -Body $body
    ```

    Or with curl.exe:

    ```powershell theme={null}
    curl.exe -X POST http://localhost:8000/v1/admin/bootstrap `
      -H "Content-Type: application/json" `
      -d "{\"name\": \"Test Hospital\", \"slug\": \"test-hospital\"}"
    ```
  </Tab>
</Tabs>

Expected response:

```json theme={null}
{
  "tenant": {
    "id": "...",
    "name": "Test Hospital",
    "slug": "test-hospital",
    "plan_tier": "free"
  },
  "api_key": "l049vdD58OQge...",
  "key_prefix": "l049vdD5",
  "note": "Save this API key — it will not be shown again."
}
```

<Warning>
  Copy the `api_key` value now — it cannot be retrieved later. Store it in an environment variable for the rest of this guide.
</Warning>

<Tabs>
  <Tab title="macOS / Linux">
    ```bash theme={null}
    export API_KEY="paste-your-key-here"
    ```
  </Tab>

  <Tab title="Windows (PowerShell)">
    ```powershell theme={null}
    $env:API_KEY = "paste-your-key-here"
    ```
  </Tab>
</Tabs>

***

## 7. Seed all reference data

This single call loads RVU fee schedules, GPCI geographic indices, NCCI coding edits (MUE + PTP + AOC), MAC contractors, CBSA mappings, Medicaid programs, and sample facilities.

<Tabs>
  <Tab title="macOS / Linux">
    ```bash theme={null}
    curl -X POST http://localhost:8000/v1/admin/data/refresh \
      -H "X-API-Key: $API_KEY"
    ```
  </Tab>

  <Tab title="Windows (PowerShell)">
    ```powershell theme={null}
    Invoke-RestMethod -Method Post -Uri http://localhost:8000/v1/admin/data/refresh `
      -Headers @{"X-API-Key" = $env:API_KEY}
    ```
  </Tab>
</Tabs>

Expected response:

```json theme={null}
{
  "status": "completed",
  "facilities_loaded": 1,
  "rvu_rows": 72,
  "gpci_rows": 111,
  "ncci_ptp_rows": 42,
  "ncci_mue_rows": 56,
  "ncci_aoc_rows": 29,
  "medicaid_programs": 50,
  "mac_contractors_loaded": 12,
  "cbsa_mappings_loaded": 12
}
```

If all counts are `0`, see [Troubleshooting](#troubleshooting).

***

## 8. Test every endpoint

The commands below use macOS/Linux `curl` syntax. On Windows, replace `curl` with `curl.exe`, replace `\` line continuations with `` ` ``, and use `$env:API_KEY` instead of `$API_KEY`.

### Knowledge resolution

```bash theme={null}
# Full L1-L6 resolution
curl http://localhost:8000/v1/knowledge/layers/170001 \
  -H "X-API-Key: $API_KEY"

# Billing guide
curl -X POST http://localhost:8000/v1/knowledge/billing-guide \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ccn": "170001", "cpt": "99213"}'

# Payment calculation
curl -X POST http://localhost:8000/v1/knowledge/payment-calc \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ccn": "170001", "cpt": "99213"}'
```

Expected payment result: `$86.02` for CPT 99213 at CCN 170001.

### NCCI MUE limits

```bash theme={null}
# Practitioner setting
curl "http://localhost:8000/v1/ncci/mue/practitioner/99213" \
  -H "X-API-Key: $API_KEY"

# Hospital Outpatient setting
curl "http://localhost:8000/v1/ncci/mue/hosp-op/99213" \
  -H "X-API-Key: $API_KEY"

# DME setting
curl "http://localhost:8000/v1/ncci/mue/dme/E0601" \
  -H "X-API-Key: $API_KEY"
```

| Setting      | Code  | Expected `mue_value` | MAI          |
| ------------ | ----- | -------------------- | ------------ |
| Practitioner | 99213 | 3                    | 3 (Clinical) |
| Hospital OP  | 99213 | 3                    | 3 (Clinical) |
| DME          | E0601 | 1                    | 2 (Policy)   |

### NCCI PTP edits

```bash theme={null}
# Practitioner table
curl "http://localhost:8000/v1/ncci/ptp/prac?col1_proc_cd=27447&col2_proc_cd=29881" \
  -H "X-API-Key: $API_KEY"

# Hospital table
curl "http://localhost:8000/v1/ncci/ptp/hosp?col1_proc_cd=27447&col2_proc_cd=29881" \
  -H "X-API-Key: $API_KEY"

# Validate a code pair
curl "http://localhost:8000/v1/ncci/validate?code1=27447&code2=29881" \
  -H "X-API-Key: $API_KEY"
```

Expected: `modifier: "1"` (modifier allowed), `is_bundled: true`.

### NCCI Add-On Code edits

```bash theme={null}
# By add-on code
curl "http://localhost:8000/v1/ncci/aoc?add_on_code=99417" \
  -H "X-API-Key: $API_KEY"

# By primary procedure
curl "http://localhost:8000/v1/ncci/aoc?primary_proc_cd=27447" \
  -H "X-API-Key: $API_KEY"
```

Expected: 99417 returns 3 primary codes (99213, 99214, 99215).

### NPI search

NPI search calls the live CMS NPPES registry. No seeded data needed.

```bash theme={null}
# Search by last name and state
curl "http://localhost:8000/v1/npi/search?last_name=Smith&state=KS&limit=3" \
  -H "X-API-Key: $API_KEY"

# Search by organization name
curl "http://localhost:8000/v1/npi/search?organization_name=Stormont+Vail&state=KS" \
  -H "X-API-Key: $API_KEY"
```

### Facilities

```bash theme={null}
# List all facilities (enriched with MAC, GPCI)
curl "http://localhost:8000/v1/facilities/" \
  -H "X-API-Key: $API_KEY"

# Get a single facility by CCN
curl "http://localhost:8000/v1/facilities/170001" \
  -H "X-API-Key: $API_KEY"
```

Expected: response includes `mac`, `gpci`, and `cbsa_detail` fields.

### AI agents

```bash theme={null}
# Submit a code research job
curl -X POST http://localhost:8000/v1/agents/code-research \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "What is CPT 99213?"}'

# Poll for result (replace JOB_ID)
curl "http://localhost:8000/v1/agents/jobs/JOB_ID" \
  -H "X-API-Key: $API_KEY"
```

<Note>
  Agent jobs require the `rcm-agents` service running at `RCM_AGENTS_URL`. Without it, jobs stay in `pending` status — the rest of the platform works independently.
</Note>

### Audit

```bash theme={null}
curl "http://localhost:8000/v1/audit/stats" \
  -H "X-API-Key: $API_KEY"

curl "http://localhost:8000/v1/audit/events?limit=10" \
  -H "X-API-Key: $API_KEY"
```

### Admin

```bash theme={null}
# Usage metrics
curl "http://localhost:8000/v1/admin/usage" \
  -H "X-API-Key: $API_KEY"

# List API keys
curl "http://localhost:8000/v1/admin/api-keys" \
  -H "X-API-Key: $API_KEY"

# Data freshness
curl "http://localhost:8000/v1/admin/data/status" \
  -H "X-API-Key: $API_KEY"

# Tracked data sources
curl "http://localhost:8000/v1/admin/data/sources" \
  -H "X-API-Key: $API_KEY"
```

***

## 9. Run the test suite

<Tabs>
  <Tab title="macOS / Linux">
    ```bash theme={null}
    # Platform tests
    pytest tests/ -v

    # SDK tests (if using the Python SDK)
    cd rci_python && pytest tests/ -v && cd ..
    ```
  </Tab>

  <Tab title="Windows (PowerShell)">
    ```powershell theme={null}
    # Platform tests
    python -m pytest tests/ -v

    # SDK tests (if using the Python SDK)
    cd rci_python
    python -m pytest tests/ -v
    cd ..
    ```
  </Tab>
</Tabs>

***

## 10. Open interactive docs

Open your browser to [http://localhost:8000/docs](http://localhost:8000/docs) for the Swagger UI. Every endpoint is documented with request/response schemas and you can execute requests directly from the browser.

***

## Sample data reference

The seed data loaded in step 7 includes:

### NCCI MUE (56 entries)

| Setting      | Codes available                                                                                                                            |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Practitioner | 99203, 99204, 99213, 99214, 99215, 27440, 27441, 27442, 27447, 29880, 29881, 36415, 71046, 73610, 80053, 85025, 10060, 12001, 99291, 96374 |
| Hospital OP  | 99213, 99214, 99215, 27440, 27441, 27442, 27447, 29880, 29881, 36415, 71046, 73610, 80053, 10060, 12001, 99291, 96374, 80061, 85027        |
| DME          | E0601, E0470, E1390, K0823, K0001, K0462, A4253, L3000, A7035, B4035, A6550, E0260, E0277, E0305, A4606, L0650                             |

### NCCI PTP (42 pairs)

Available in both **professional** (`/ptp/prac`) and **institutional** (`/ptp/hosp`) tables.

| Column 1 | Column 2 | Modifier | Rationale                              |
| -------- | -------- | -------- | -------------------------------------- |
| 27447    | 27440    | 0        | More extensive procedure               |
| 27447    | 29881    | 1        | HCPCS/CPT procedure code definition    |
| 99213    | 99214    | 0        | Mutually exclusive procedures          |
| 80053    | 85025    | 0        | Laboratory panel                       |
| 10060    | 12001    | 1        | Standards of medical/surgical practice |

### NCCI AOC (29 relationships)

| Primary | Add-On | Type | Notes                                    |
| ------- | ------ | ---- | ---------------------------------------- |
| 99213   | 99417  | 2    | Contractor Defined Primary Codes         |
| 27447   | 22614  | 1    | Limited list                             |
| 99291   | 99292  | 1    | Limited list                             |
| 96374   | 96376  | 3    | 96376 may be reported by facilities only |

### Other reference data

| Dataset           | Rows | Source                   |
| ----------------- | ---- | ------------------------ |
| RVU fee schedule  | 72   | `pprrvu26_sample.csv`    |
| GPCI localities   | 111  | `gpci2026.csv`           |
| Medicaid programs | 50   | `medicaid_programs.yaml` |
| MAC contractors   | 12   | `mac_contractors.yaml`   |
| CBSA mappings     | 12   | `cbsa_mappings.yaml`     |

***

## Troubleshooting

### Data refresh returns all zeros

If `POST /v1/admin/data/refresh` returns `0` for all row counts:

1. **Docker stack**: Make sure you started the full stack with `docker compose up -d` (not just `postgres redis`). The API container needs access to the `data/` directory via volume mount.

2. **Local dev server**: If running with `uvicorn` directly, the data files are resolved from the project root. Make sure you're running from the repository root directory.

3. **Verify files exist**: Check that the `data/cms/` directory contains the CSV files:

```bash theme={null}
ls data/cms/
# Should show: gpci2026.csv  ncci_aoc_sample.csv  ncci_mue_sample.csv
#              ncci_ptp_sample.csv  pprrvu26_sample.csv  medicaid_programs.yaml
```

### Migration errors: duplicate\_object

If `alembic upgrade head` fails with `type "..." already exists`:

```bash theme={null}
# Option 1: Clean up and retry
docker compose down -v     # Removes volumes (deletes all data)
docker compose up -d
alembic upgrade head

# Option 2: Drop orphaned types from a partial run
docker exec platform-postgres-1 psql -U hkl -d hkl -c "
  DROP TABLE IF EXISTS data_sources, cbsa_mappings, gpci_localities, mac_contractors;
  DROP TYPE IF EXISTS datasourcetype, syncstatus;
"
alembic upgrade head
```

### Windows: curl syntax

PowerShell requires different quoting rules than bash:

```powershell theme={null}
# Use curl.exe (not the PowerShell alias)
curl.exe -X POST http://localhost:8000/v1/admin/bootstrap `
  -H "Content-Type: application/json" `
  -d "{\"name\": \"Test Hospital\", \"slug\": \"test-hospital\"}"

# Or use Invoke-RestMethod for cleaner output
$headers = @{"X-API-Key" = $env:API_KEY}
Invoke-RestMethod -Uri "http://localhost:8000/v1/ncci/mue/practitioner/99213" `
  -Headers $headers
```

### Windows: uvicorn not found

If `uvicorn` is not recognized:

```powershell theme={null}
python -m uvicorn kustode_platform.main:app --reload --port 8000
```

### Agent jobs stuck in pending

Agent jobs require the `rcm-agents` service. If it's not running:

* Jobs will be created with `status: "pending"` but never complete
* All other endpoints (knowledge, NCCI, NPI, facilities, audit) work independently
* Set `RCM_AGENTS_URL` in `.env` to point to a running rcm-agents instance

### Redis connection refused

If NPI search or rate limiting fails:

```bash theme={null}
# Check Redis is running
docker compose ps redis

# Restart if needed
docker compose restart redis
```

***

## Cleanup

```bash theme={null}
# Stop all containers and remove volumes
docker compose down -v

# Deactivate virtual environment
deactivate

# Remove virtual environment (optional)
rm -rf .venv          # macOS/Linux
rmdir /s /q .venv     # Windows
```
