feat(sp36): extract config router

Move GET /api/config/payers and GET /api/config/payers/{payer_id}/configs from api.py to api_routers/config.py. Both endpoints are read-only configuration surfaces used by the UI's 'Edit payers' page. Behaviour-preserving.
This commit is contained in:
Nora
2026-07-06 15:01:58 -06:00
parent 5028628269
commit 6a5dbdf88a
3 changed files with 56 additions and 23 deletions
-23
View File
@@ -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
@@ -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
+54
View File
@@ -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