docs: surface SP14 (Payer-Rejected UI + acknowledge) + SP15 (key rotation) #3

Closed
tyler wants to merge 14 commits from docs/sp14-15-readme-sync into main
Showing only changes of commit 81aebf54ed - Show all commits
+43 -3
View File
@@ -418,6 +418,35 @@ was a one-file change (`sftp_paramiko.py` replacing `sftp_stub.py`).
the `paramiko` extras aren't installed so the test suite stays green on
Linux dev boxes.
## Inbound MFT Scheduler (SP16)
The dzinesco SFTP server accepts inbound files (835 remits, 999/TA1
acks, 271 eligibility responses, 277/277CA claim acknowledgments) that
need to be pulled on a cadence, parsed, and persisted. SP16 ships the
**operator-facing control surface** for the polling loop, even though
the actual background scheduler is still in flight:
| Method | Path | Notes |
| ------ | --------------------------------------------- | ---------------------------------------------------------------- |
| POST | `/api/admin/scheduler/start` | Start the background MFT polling loop (idempotent). |
| POST | `/api/admin/scheduler/stop` | Stop the background loop. Waits for the current tick to finish. |
| GET | `/api/admin/scheduler/status` | Running state + last tick summary. |
| POST | `/api/admin/scheduler/tick` | Force a single poll cycle. Coalesces with an in-flight tick. |
| GET | `/api/admin/scheduler/processed-files` | Recently processed inbound files. `?status=ok|error|skipped|pending`, `?limit=` (1500, default 50). |
The endpoints read from a `cyclone.scheduler` module and a
`cyclone.db.ProcessedInboundFile` ORM model that are being landed
alongside SP16 — the admin router's import surface is in place, the
implementation is in progress. The control surface is forward-compatible
with the eventual scheduler: starting / stopping / ticking / listing
processed files will all work as soon as the loop lands.
The `paramiko` SFTP client from [SP13](#sftp-wire-up-paramiko) is the
underlying transport; the scheduler reuses it to list + download files
under the inbound SFTP path, then dispatches each downloaded file to
the matching parser based on the `<FileType>` token in the filename
(see [SP13 file-naming template](#sftp-wire-up-paramiko)).
## Batches, Reconciliation, and Activity
These read/write endpoints are the core operator surface for browsing
@@ -474,20 +503,31 @@ backup API).
.
├── backend/
│ ├── src/cyclone/
│ │ ├── api.py # FastAPI app + parse routes; mounts api_routers/* sub-apps
│ │ ├── api.py # FastAPI app + middleware; mounts api_routers/* sub-apps
│ │ ├── api_helpers.py # NDJSON / content-negotiation / live-tail helpers
│ │ ├── api_routers/ # FastAPI APIRouters extracted from api.py
│ │ │ ├── health.py # GET /api/health
│ │ │ ├── acks.py # GET /api/acks, /api/acks/{id}
│ │ │ ├── ta1_acks.py # GET /api/ta1-acks, /api/ta1-acks/{id}
│ │ │ ├── activity.py # GET /api/activity, /api/activity/stream
│ │ │ ├── batches.py # GET /api/batches, /api/batches/{id}, /api/batch-diff
│ │ │ ├── batches.py # GET /api/batches, /api/batches/{id}
│ │ │ ├── claims.py # GET /api/claims, /api/claims/stream, /api/claims/{id},
│ │ │ │ # /api/claims/{id}/serialize-837, /api/claims/{id}/line-reconciliation
│ │ │ ├── remittances.py # GET /api/remittances, /api/remittances/stream, /api/remittances/{id}
│ │ │ ├── providers.py # GET /api/providers
│ │ │ ├── inbox.py # GET /api/inbox/lanes, POST /api/inbox/* (match/dismiss/acknowledge/resubmit),
│ │ │ │ # GET /api/inbox/export.csv
│ │ │ ├── reconciliation.py # GET /api/reconciliation/unmatched, /api/batch-diff,
│ │ │ │ # POST /api/reconciliation/match, /api/reconciliation/unmatch
│ │ │ ├── eligibility.py # POST /api/eligibility/request, /api/eligibility/parse-271
│ │ │ ├── clearhouse.py # GET /api/clearhouse, POST /api/clearhouse/submit
│ │ │ ── config.py # /api/config/providers[/...], /api/config/payers[/...], /api/admin/reload-config
│ │ │ ── config.py # /api/config/providers[/...], /api/config/payers[/...], /api/admin/reload-config
│ │ │ ├── parse_835.py # POST /api/parse-835
│ │ │ ├── parse_837.py # POST /api/parse-837
│ │ │ ├── parse_999.py # POST /api/parse-999
│ │ │ ├── parse_ta1.py # POST /api/parse-ta1
│ │ │ └── admin.py # /api/admin/audit-log[/verify], /api/admin/db/rotate-key,
│ │ │ # /api/admin/scheduler/* (SP16)
│ │ ├── pubsub.py # in-process EventBus (drop-oldest, per-kind fan-out)
│ │ ├── store.py # CycloneStore, mappers, publish-on-write
│ │ ├── db.py # SQLAlchemy engine, session factory, ORM models