docs(sp42): README.md — refresh auth/bind claim, project layout, streaming endpoints, sub-project count
This commit is contained in:
@@ -2,12 +2,17 @@
|
||||
|
||||
A self-hosted EDI claims management suite for a single billing office.
|
||||
Parses 837P professional claims and 835 ERA remittances (X12 005010X222A1
|
||||
and 005010X221A1), with a local-only FastAPI backend and a React UI for
|
||||
browsing, filtering, and inspecting the parsed data.
|
||||
and 005010X221A1), with a FastAPI backend and a React UI for browsing,
|
||||
filtering, and inspecting the parsed data.
|
||||
|
||||
Local-only on purpose: binds to `127.0.0.1`, no auth, no internet exposure.
|
||||
Built for one operator, one machine, one trading partner (Colorado
|
||||
Medicaid, currently).
|
||||
LAN-only by design: always binds to `0.0.0.0:8000` and requires login
|
||||
(bcrypt + HttpOnly session cookie; first admin bootstrapped from
|
||||
`CYCLONE_ADMIN_USERNAME` + `CYCLONE_ADMIN_PASSWORD`). Reachability is
|
||||
controlled by the host firewall / compose port publishing, not by the
|
||||
bind address. Built for one operator, one machine, one trading partner
|
||||
(Colorado Medicaid, currently). Do not expose the published ports to
|
||||
the public internet. See [SP23](docs/superpowers/specs/2026-06-22-cyclone-ubuntu-docker-deployment-design.md)
|
||||
for the LAN-bind / Docker / RBAC product fork that shipped 2026-06-23.
|
||||
|
||||
## Install
|
||||
|
||||
@@ -185,12 +190,14 @@ happening — clients flip to `stalled` after 30s of total silence
|
||||
### Endpoints
|
||||
|
||||
| Method | Path | Subscribes to | Default sort |
|
||||
| ------ | -------------------------- | ------------------- | ------------------- |
|
||||
| ------ | -------------------------- | -------------------- | ------------------- |
|
||||
| GET | `/api/claims/stream` | `claim_written` | `-submission_date` |
|
||||
| GET | `/api/remittances/stream` | `remittance_written`| `-received_date` |
|
||||
| GET | `/api/remittances/stream` | `remittance_written` | `-received_date` |
|
||||
| GET | `/api/activity/stream` | `activity_recorded` | `-timestamp` (limit 50) |
|
||||
| GET | `/api/acks/stream` | `ack_received` | `-received_date` |
|
||||
| GET | `/api/ta1-acks/stream` | `ta1_ack_received` | `-received_date` |
|
||||
|
||||
All three accept the same query params as their non-streaming
|
||||
All five accept the same query params as their non-streaming
|
||||
counterparts (`status`, `payer`, `date_from`, …) so a frontend can
|
||||
swap a one-shot fetch for a tail with no URL surgery. Responses
|
||||
are `Content-Type: application/x-ndjson`.
|
||||
@@ -743,12 +750,11 @@ backup API).
|
||||
.
|
||||
├── backend/
|
||||
│ ├── src/cyclone/
|
||||
│ │ ├── api.py # FastAPI app, GET + parse routes, /api/{resource}/stream
|
||||
│ │ ├── api.py # FastAPI app shell (~377 LOC post-SP36; routes live in api_routers/)
|
||||
│ │ ├── api_helpers.py # NDJSON / content-negotiation / live-tail helpers
|
||||
│ │ ├── 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
|
||||
│ │ ├── db_migrate.py # PRAGMA user_version migration runner
|
||||
│ │ ├── db_migrate.py # PRAGMA user_version migration runner (23 migrations)
|
||||
│ │ ├── db_crypto.py # optional SQLCipher encryption at rest (SP12)
|
||||
│ │ ├── audit_log.py # tamper-evident hash-chained audit_log (SP11)
|
||||
│ │ ├── inbox_lanes.py # rejected / payer_rejected / candidates / unmatched / done_today
|
||||
@@ -756,37 +762,45 @@ backup API).
|
||||
│ │ ├── inbox_state_277ca.py # 277CA STC A4/A6/A7 → payer_rejected stamp (SP10)
|
||||
│ │ ├── providers.py # multi-NPI provider lookups (SP9)
|
||||
│ │ ├── payers.py # payer / payer_config lookups (SP9)
|
||||
│ │ ├── secrets.py # macOS Keychain-backed secret fetcher
|
||||
│ │ ├── reconcile.py # pure-function 835→claim match + line-level match
|
||||
│ │ ├── __main__.py # `python -m cyclone serve`
|
||||
│ │ ├── cli.py # click CLI
|
||||
│ │ └── parsers/ # X12 tokenizer, models, validator, writers, 277CA, 999, TA1, 270, 271
|
||||
│ └── tests/
|
||||
│ ├── fixtures/ # co_medicaid_*.txt, minimal_*.txt
|
||||
│ ├── test_api.py # parse-837/835 round-trip
|
||||
│ ├── test_api_gets.py # 6 GET endpoints
|
||||
│ ├── test_store.py # store + mappers + iterators
|
||||
│ ├── test_api_streaming.py
|
||||
│ ├── test_api_stream_live.py # 3 live-tail endpoints + disconnect cleanup
|
||||
│ ├── test_pubsub.py # EventBus + subscribe/unsubscribe
|
||||
│ ├── test_api_parse_persists.py
|
||||
│ ├── test_db.py / test_db_crypto.py / test_db_migrate.py
|
||||
│ ├── test_audit_log.py
|
||||
│ ├── test_inbox_lanes.py / test_inbox_state.py
|
||||
│ ├── test_apply_277ca_rejections.py
|
||||
│ ├── test_sftp_stub.py / test_sftp_paramiko.py
|
||||
│ └── test_providers_seed.py / test_payer_config_loading.py
|
||||
├── src/ # React + Vite + TypeScript UI
|
||||
│ │ ├── secrets.py # macOS Keychain-backed secret fetcher (4-tier: _FILE > env > Keychain > None)
|
||||
│ │ ├── reconcile.py # pure-function 835→claim match + line-level match (SP31 pcn-exact)
|
||||
│ │ ├── scheduler.py # inbound MFT polling scheduler (SP16, SP27 per-op timeout)
|
||||
│ │ ├── edifabric.py # Edifabric /v2/x12/{read,validate} HTTP client (SP40)
|
||||
│ │ ├── backup.py / backup_service.py / backup_scheduler.py # SP17 encrypted backups
|
||||
│ │ ├── __main__.py # `python -m cyclone serve` (auth bootstrap then dispatch)
|
||||
│ │ ├── cli.py # click CLI (15+ subcommands; see cyclone-cli skill)
|
||||
│ │ ├── api_routers/ # SP36 — 22 FastAPI routers + _shared.py helpers
|
||||
│ │ ├── auth/ # SP24 — bcrypt + sessions + matrix_gate + admin users + rate_limit
|
||||
│ │ ├── clearhouse/ # SftpClient + InboundFile + SftpStat
|
||||
│ │ ├── edi/ # filename regex/builder helpers
|
||||
│ │ ├── handlers/ # SP27 — per-file-type inbound parse handlers
|
||||
│ │ ├── parsers/ # X12 tokenizer, models, validator, writers, 277CA, 999, TA1, 270, 271
|
||||
│ │ ├── rebill/ # SP41 — in-window rebill pipeline (13 modules)
|
||||
│ │ ├── reissue/ # SP24 — offline 837P reissue workflow
|
||||
│ │ ├── store/ # SP21 — split CycloneStore facade (16 modules)
|
||||
│ │ └── submission/ # SP37 — canonical submit_file helper + recover + bulk_ingest
|
||||
│ └── tests/ # 178 pytest files (post-SP41)
|
||||
│ ├── fixtures/ # 22 entries (837P / 835 / 999 / TA1 / 277CA samples + visits CSV)
|
||||
│ ├── test_api_*.py # FastAPI integration via TestClient
|
||||
│ ├── test_*.py # pure-unit
|
||||
│ └── ...
|
||||
├── src/ # React + Vite + TypeScript UI (12 pages, 84 test files)
|
||||
│ ├── components/
|
||||
│ │ ├── ui/ # Skeleton, EmptyState, ErrorState, FilterChips, Pagination, …
|
||||
│ │ ├── ClaimDrawer/ # 12 sibling tests
|
||||
│ │ ├── RemitDrawer/ # 8 sibling tests
|
||||
│ │ ├── ProviderDrawer/ # right-anchored side panel
|
||||
│ │ ├── AckDrawer/ # right-anchored side panel (SP28 ack-claim auto-link)
|
||||
│ │ ├── inbox/ # 5-lane triage surface (SP14)
|
||||
│ │ ├── drill/ # DrillStackProvider + DrillableCell + PeekModal
|
||||
│ │ └── TailStatusPill.tsx # live-tail status badge + reconnect button
|
||||
│ ├── pages/ # Claims, Remittances, Providers, Acks, Activity, Upload, Inbox, …
|
||||
│ ├── pages/ # Dashboard, Claims, Remittances, Providers, ActivityLog,
|
||||
│ │ # Upload, Reconciliation, Inbox, Acks, Batches, BatchDiff, Login
|
||||
│ ├── hooks/ # useBatches, useClaims, useRemittances, useProviders, useActivity, useParse
|
||||
│ │ # + useTailStream, useMergedTail (live tail)
|
||||
│ ├── lib/ # api.ts, format.ts, utils.ts
|
||||
│ │ # + tail-stream.ts (NDJSON parser)
|
||||
│ ├── store/ # zustand sample-data + parsed-batches store
|
||||
│ │ # + tail-store.ts (FIFO-capped live tail slices)
|
||||
│ │ # + useTailStream, useMergedTail (live tail triplet)
|
||||
│ ├── auth/ # AuthProvider, RoleGate, api client (SP24)
|
||||
│ ├── lib/ # api.ts, format.ts, utils.ts, tail-stream.ts (NDJSON parser), inbox-api.ts
|
||||
│ ├── store/ # zustand useAppStore (sample data) + useTailStore (FIFO-capped live tail slices)
|
||||
│ └── types/ # shared TS types
|
||||
├── config/
|
||||
│ └── payers.yaml # YAML-driven payer + clearhouse config (SP9)
|
||||
@@ -807,11 +821,15 @@ backup API).
|
||||
> 3. The per-SP spec under [`docs/superpowers/specs/`](docs/superpowers/specs/) for whatever you're touching.
|
||||
> 4. The per-SP plan under [`docs/superpowers/plans/`](docs/superpowers/plans/) if you're implementing.
|
||||
|
||||
Sub-projects 2 through 19 are **shipped**. See the [completeness
|
||||
Sub-projects 2 through 41 are **shipped** (last merged: SP41 in-window
|
||||
rebill pipeline, `merge: SP41 inwindow-rebill-pipeline into main` at
|
||||
`309e6c0`). See the [completeness
|
||||
review](docs/reviews/2026-06-20-cyclone-completeness-review.md) for
|
||||
the honest gap analysis against the industry definition of a HIPAA
|
||||
clearinghouse — the short version is that the local-only,
|
||||
single-operator, single-payer design contract is honored, and the
|
||||
clearinghouse — the short version is that the LAN-only,
|
||||
single-operator, single-payer design contract is honored (auth per
|
||||
SP23, encryption at rest via SQLCipher per SP12, RBAC per SP23, audit
|
||||
log per SP11), and the
|
||||
items that would be needed to expand that contract (AS2/AS4, SNIP 1–7,
|
||||
HITRUST, 276/277 status, 278 referrals, COB) are intentionally out of
|
||||
scope.
|
||||
|
||||
Reference in New Issue
Block a user