feat(sp6): wire 999 ingest → claim rejected state

T4 — calls apply_999_rejections inside /api/parse-999, then
publishes a claim.rejected event for each transitioned claim so
the Inbox live-tail refetches.
This commit is contained in:
Tyler
2026-06-20 18:29:28 -06:00
parent 78ed75a31d
commit f4910fd94d
2 changed files with 100 additions and 0 deletions
+25
View File
@@ -29,6 +29,7 @@ from fastapi.responses import JSONResponse, StreamingResponse
from pydantic import ValidationError
from cyclone import __version__
from cyclone.inbox_state import apply_999_rejections
from cyclone.parsers.exceptions import CycloneParseError
from cyclone.parsers.models import BatchSummary, ClaimOutput, Envelope, ParseResult
from cyclone.parsers.models_270 import (
@@ -568,6 +569,7 @@ def _ack_synthetic_source_batch_id(interchange_control_number: str) -> str:
@app.post("/api/parse-999")
async def parse_999_endpoint(
request: Request,
file: UploadFile = File(...),
) -> Any:
"""Parse a 999 ACK file, persist a row, and return JSON.
@@ -617,6 +619,29 @@ async def parse_999_endpoint(
# Build the raw 999 text from the parsed result (round-trip).
raw_999_text = serialize_999(result, interchange_control_number=icn or "000000001")
# SP6 T4: move claims whose 999 set was rejected into ClaimState.REJECTED.
# The 999's set_control_number (AK202) is the source 837's ST02; in
# practice we look it up against patient_control_number because that's
# the field 999 ACKs cross-reference in this product.
from cyclone import db as _db
from cyclone.db import Claim
with _db.SessionLocal()() as session:
def _lookup(pcn: str):
return session.query(Claim).filter_by(patient_control_number=pcn).first()
_rejection_result = apply_999_rejections(
session, result, claim_lookup=_lookup,
)
if _rejection_result.matched:
bus = request.app.state.event_bus
for cid in _rejection_result.matched:
await bus.publish("claim.rejected", {"claim_id": cid})
if _rejection_result.orphans:
log.warning(
"999 had %d orphan set refs: %s",
len(_rejection_result.orphans),
_rejection_result.orphans[:5],
)
row = store.add_ack(
source_batch_id=synthetic_id,
accepted_count=accepted,