diff --git a/backend/src/cyclone/api.py b/backend/src/cyclone/api.py index 995f5a6..bd537d4 100644 --- a/backend/src/cyclone/api.py +++ b/backend/src/cyclone/api.py @@ -3162,31 +3162,8 @@ def get_configured_provider(npi: str): return provider_dict -@app.get("/api/config/payers", dependencies=[Depends(matrix_gate)]) -def list_configured_payers(is_active: bool | None = Query(default=True)): - return [json.loads(p.model_dump_json()) for p in store.list_payers(is_active=is_active)] - - -@app.get("/api/config/payers/{payer_id}/configs", dependencies=[Depends(matrix_gate)]) -def list_payer_configs(payer_id: str): - """List all (transaction_type, config_json) blocks for a payer.""" - from cyclone import payers as payer_loader - configs = [ - {"transaction_type": tx, "config_json": block, "source": "yaml"} - for (pid, tx), block in payer_loader.all_configs().items() - if pid == payer_id - ] - # Also check the DB for runtime-overridden configs - for tx in ("837P", "835", "277CA", "999", "TA1"): - live = store.get_payer_config(payer_id, tx) - if live is not None: - configs.append({"transaction_type": tx, "config_json": live, "source": "db"}) - return configs - - # --------------------------------------------------------------------------- # - from cyclone.auth.routes import router as auth_router from cyclone.auth.admin import router as admin_users_router diff --git a/backend/src/cyclone/api_routers/__init__.py b/backend/src/cyclone/api_routers/__init__.py index 9fe7b58..432032e 100644 --- a/backend/src/cyclone/api_routers/__init__.py +++ b/backend/src/cyclone/api_routers/__init__.py @@ -14,6 +14,7 @@ from cyclone.api_routers import ( acks, admin, claim_acks, + config, dashboard, eligibility, health, @@ -25,6 +26,7 @@ routers: list[APIRouter] = [ acks.router, # gated admin.router, # gated claim_acks.router, # gated + config.router, # gated dashboard.router, # gated eligibility.router, # gated health.router, # public — health probes must work pre-auth diff --git a/backend/src/cyclone/api_routers/config.py b/backend/src/cyclone/api_routers/config.py new file mode 100644 index 0000000..7084413 --- /dev/null +++ b/backend/src/cyclone/api_routers/config.py @@ -0,0 +1,54 @@ +"""``/api/config/payers`` and ``/api/config/payers/{payer_id}/configs`` — payer-config read views. + +Both endpoints are read-only configuration surfaces used by the UI's +"Edit payers" page: + +- ``GET /api/config/payers?is_active=...`` lists all configured + payers (PayerConfig records) — the set of payers the operator has + registered, regardless of whether they have inbound config blocks. +- ``GET /api/config/payers/{payer_id}/configs`` returns the full + list of ``(transaction_type, config_json)`` blocks for a given + payer. Each block has a ``source``: ``"yaml"`` for the on-disk + ``config/payers.yaml`` default, ``"db"`` for any runtime override + recorded via ``/api/admin/reload-config``. + +These are configuration surfaces, not claim-processing surfaces. +They live here (under ``/api/config/``) rather than under +``/api/payers/`` because the latter is the drill-down rollup +(see ``api_routers/payers.py``). + +SP36 Task 7: this block moved here from ``api.py:3167`` (after +the SP21 provider-detail helper, before the Auth routers divider). +""" +from __future__ import annotations + +import json + +from fastapi import APIRouter, Depends, Query + +from cyclone import store +from cyclone.auth.deps import matrix_gate + +router = APIRouter(dependencies=[Depends(matrix_gate)]) + + +@router.get("/api/config/payers") +def list_configured_payers(is_active: bool | None = Query(default=True)): + return [json.loads(p.model_dump_json()) for p in store.list_payers(is_active=is_active)] + + +@router.get("/api/config/payers/{payer_id}/configs") +def list_payer_configs(payer_id: str): + """List all (transaction_type, config_json) blocks for a payer.""" + from cyclone import payers as payer_loader + configs = [ + {"transaction_type": tx, "config_json": block, "source": "yaml"} + for (pid, tx), block in payer_loader.all_configs().items() + if pid == payer_id + ] + # Also check the DB for runtime-overridden configs + for tx in ("837P", "835", "277CA", "999", "TA1"): + live = store.get_payer_config(payer_id, tx) + if live is not None: + configs.append({"transaction_type": tx, "config_json": live, "source": "db"}) + return configs