docs(spec): SP32 simplify D4/D6 — single-NPI per Remit, no comma-aggregation
This commit is contained in:
@@ -11,7 +11,7 @@ Status: Draft, awaiting user sign-off.
|
||||
- **Persist** all three new fields in their typed columns AND mirror to `raw_json` for audit and fallback reads.
|
||||
- **Backfill** existing rows by re-parsing on-disk files via a new CLI subcommand.
|
||||
- **Re-reconcile** open claim/remit pairs after backfill so the NPI arm of SP31's 2-of-3 content-match rule can actually fire on historical data.
|
||||
- **Widen** `_content_keys_match` in `reconcile.py` to read the new NPI sources (typed-column primary, `raw_json` fallback) and to treat a comma-separated `Remittance.rendering_provider_npi` as a set.
|
||||
- **Widen** `_content_keys_match` in `reconcile.py` to read the new NPI sources (typed-column primary, `raw_json` fallback).
|
||||
|
||||
### Out of scope
|
||||
|
||||
@@ -34,9 +34,9 @@ Add `ClaimPayment.service_provider_npi: str | None` to `backend/src/cyclone/pars
|
||||
|
||||
Add `Claim.rendering_provider_npi: Mapped[Optional[str]] = mapped_column(String(16), nullable=True)` to `backend/src/cyclone/db.py`. Mirrors the existing `Claim.provider_npi` column. Schema migration `0016_add_rendering_and_service_provider_npis.sql` adds both this and the next column.
|
||||
|
||||
### D4 — Per-Remit aggregated column for the matcher
|
||||
### D4 — Per-Remit column for the matcher
|
||||
|
||||
Add `Remittance.rendering_provider_npi: Mapped[Optional[str]] = mapped_column(String(64), nullable=True)` (length-64 accommodates comma-separated lists up to ~6 NPI strings with separators). For multi-CLP remits, the writer concatenates each `ClaimPayment.service_provider_npi` with `","` as the separator (e.g. `"1234567890,0987654321"`). Single-CLP remits store the single NPI as-is. `None` means no CLP in the remit had a service-provider NPI.
|
||||
Add `Remittance.rendering_provider_npi: Mapped[Optional[str]] = mapped_column(String(16), nullable=True)`. Today, each `Remittance` row corresponds to exactly one `ClaimPayment` (the write layer keys Remittance by `cp.payer_claim_control_number`; see `store/write.py:134`), so the column holds the single NPI for that segment (or `None`). The column is left unaggregated to keep the schema simple — if multi-CLP-per-Remit support is added in a future SP, the schema is large enough (`String(16)`) to upgrade to comma-joined storage without re-migration. The matcher's NPI arm reads this column directly.
|
||||
|
||||
### D5 — `raw_json` mirrors
|
||||
|
||||
@@ -110,7 +110,7 @@ No `UPDATE` statements in the migration — backfill is a separate, deliberate s
|
||||
| `NM1*1P` missing or `1P` qualifier absent in a CLP segment | `ClaimPayment.service_provider_npi = None`. Matcher's NPI arm simply doesn't fire for that key. |
|
||||
| `NM1*82` missing or empty in an 837p claim | `Claim.rendering_provider_npi = None`. Same graceful degrade. |
|
||||
| `NM1*1P` with `NM109` empty | Treat as missing — store `None`, never empty string. |
|
||||
| Multi-CLP remit with mixed NPIs | Writer aggregates `"<npi1>,<npi2>,..."` on `Remittance.rendering_provider_npi`. Per-segment NPIs still on `ClaimPayment.service_provider_npi`. |
|
||||
| Multi-CLP per Remit in a future SP | Schema-size forward note (D4). Today, each Remit = one CLP = single NPI, no aggregation needed. |
|
||||
| 837p rendering NPI == billing NPI (solo practice) | Both columns populated independently. Matcher compares against the service-provider NPI; identity is coincidence in this case. |
|
||||
| Backfill on a deleted-on-disk file | CLI logs a WARNING, skips the batch. Typed columns stay NULL for unmatched rows. Existing match state untouched. |
|
||||
| Re-reconcile creates new `score-auto` matches | Each emits an `auto_matched_835` ActivityEvent per SP31 D8 (D8). Audit trail is explicit. |
|
||||
|
||||
Reference in New Issue
Block a user