Commit Graph

145 Commits

Author SHA1 Message Date
Tyler c3306b882a chore(backend): move import json to module top in store.py 2026-06-19 22:45:25 -06:00
Tyler c8bc2c73e6 feat(backend): SQLAlchemy-backed CycloneStore (T9)
Replace the in-memory InMemoryStore with a SQLAlchemy-backed
CycloneStore that persists Batch, Claim, Remittance, Match, and
ActivityEvent rows to a configurable DB engine (sqlite by default,
overridable via CYCLONE_DB_URL).

Public API preserved: add / get_batch / iter_claims / iter_remittances
/ distinct_providers / recent_activity. New T10/T12 stubs:
list_unmatched, manual_match, manual_unmatch.

Backward-compat shims for tests that called ._batches.clear() or
acquired ._lock as a context manager.

Idempotency: add() does a per-row session.get(Claim, c.id) (and
s.get(Remittance, ...)) check before each insert; duplicates are
skipped with a warning. This makes re-uploading the same fixture
idempotent instead of raising IntegrityError on the PK.

Auto-init DB fixture (backend/tests/conftest.py) sets
CYCLONE_DB_URL to a per-test sqlite file and calls db.init_db()
once per test, replacing the old module-scoped in-memory fixture.
2026-06-19 22:37:12 -06:00
Tyler 00371248b3 feat(backend): add apply_payment, apply_reversal, split_unmatched pure fns 2026-06-19 22:10:44 -06:00
Tyler c13bbf9190 docs(backend): reconcile Protocol — patient_control_number is Optional[str] 2026-06-19 22:04:30 -06:00
Tyler c30416e68c feat(backend): add reconcile.match with date-window + multi-claim fallback 2026-06-19 21:59:23 -06:00
Tyler 05a49be964 feat(backend): add Match + ActivityEvent ORM models 2026-06-19 21:53:52 -06:00
Tyler 846944448a feat(backend): harden T5 — divergence comment + invariant tests 2026-06-19 21:51:43 -06:00
Tyler 0cc74dc173 feat(backend): add Remittance + CasAdjustment ORM models 2026-06-19 21:47:18 -06:00
Tyler 2019a651ed feat(backend): fix T4 index drift, lazy import, FK policy, expand test coverage 2026-06-19 21:42:11 -06:00
Tyler 0fdb760bc1 docs(backend): update db.py docstring to reflect migrations-first order 2026-06-19 21:36:26 -06:00
Tyler 5be6299b3a feat(backend): add Batch + Claim ORM models + ClaimState enum 2026-06-19 21:36:02 -06:00
Tyler 934d623d3a feat(backend): harden db_migrate — rollback test, non-sql filter test, doc convention 2026-06-19 21:25:15 -06:00
Tyler 1bd2334e40 feat(backend): add PRAGMA user_version migration runner + 0001_initial 2026-06-19 21:19:43 -06:00
Tyler 854078a726 feat(backend): add cyclone.db with engine, SessionLocal, Base, init_db 2026-06-19 21:03:21 -06:00
Tyler 4abc03a003 build(backend): add sqlalchemy>=2.0,<3 dependency 2026-06-19 20:58:57 -06:00
Tyler 300522aac1 fix(backend): default GET list endpoints to JSON per spec 6.2
Spec 6.2 says: 'Default JSON response wraps the same data in a
{items, total, returned, has_more} envelope so the frontend can
paginate uniformly.' Previously the GET list endpoints defaulted
to NDJSON (consistent with the parse endpoints), which forced
every curl call to set Accept: application/json.

Now NDJSON is strictly opt-in via Accept: application/x-ndjson;
JSON is the default. Parse endpoints keep their existing NDJSON
default (browser uploads).

T8 test 'test_claims_default_accept_returns_ndjson' updated to
assert the new default.
2026-06-19 19:32:45 -06:00
Tyler 07ceeaf4cd feat(backend): bind serve to 127.0.0.1:8000, honor CYCLONE_PORT/CYCLONE_RELOAD 2026-06-19 19:30:55 -06:00
Tyler 74a673a360 feat(backend): add NDJSON streaming on list endpoints 2026-06-19 19:28:17 -06:00
Tyler cbffdbd2af feat(backend): add GET /api/{remittances,providers,activity} 2026-06-19 19:26:58 -06:00
Tyler cab8ff6656 feat(backend): add GET /api/claims with filter/sort/pagination 2026-06-19 19:26:17 -06:00
Tyler 39379d2d5e feat(backend): add GET /api/batches and GET /api/batches/{id} 2026-06-19 19:25:54 -06:00
Tyler 86e69d5b95 feat(backend): wire parse-837/parse-835 to persist to InMemoryStore 2026-06-19 19:25:23 -06:00
Tyler ca645db518 refactor(store): code quality fixes per review
- iter_claims/iter_remittances now return list[dict] (snapshot under
  the lock, return outside) so slow consumers no longer hold the
  write lock during iteration
- iter_claims gains payer (case-insensitive substring) and
  date_from/date_to filters via the new _date_in_bounds helper
- iter_remittances wires date_from/date_to and payer
- BatchRecord split into BatchRecord837 / BatchRecord835 with
  __new__ dispatch so isinstance narrows result correctly,
  eliminating the four 'type: ignore[assignment]' band-aids
- BatchRecord now rejects naive parsed_at via model_validator
- to_ui_remittance's adjustmentAmount=0.0 is documented as a
  TODO for sub-project 2 reconciliation

151 passed, 1 skipped (no regressions; +6 tests for new filters)
2026-06-19 19:22:44 -06:00
Tyler d0411b8186 fix(store): spec compliance fixes per review 2026-06-19 19:13:52 -06:00
Tyler 0fa80e29d5 feat(backend): add store iterators (claims, remits, providers, activity) 2026-06-19 19:06:10 -06:00
Tyler 2a78d129ca feat(backend): add store mappers (claim, remittance, provider, activity) 2026-06-19 19:05:42 -06:00
Tyler 112c08fe14 feat(backend): add cyclone.store with BatchRecord and InMemoryStore 2026-06-19 19:04:53 -06:00
Tyler 12ac72f915 fix(backend): make 835 summary counts consistent with total_claims 2026-06-19 17:07:54 -06:00
Tyler 8ea951f436 feat(backend): 835 ERA parser with BPR/CLP/SVC balancing, CO Medicaid config, CLI, and FastAPI route 2026-06-19 17:01:57 -06:00
Tyler 3dff38045a Merge feat/api-endpoint: FastAPI surface with NDJSON streaming and CORS for Vite 2026-06-19 16:41:21 -06:00
Tyler eb7d42d2d8 feat(backend): tighten CLM05 validation for CO Medicaid (CLM05-1 POS, CLM05-2 qualifier) 2026-06-19 16:39:02 -06:00
Tyler 07a8fbb720 feat(backend): FastAPI endpoint with NDJSON streaming and CORS for Vite frontend 2026-06-19 16:35:53 -06:00
Tyler 464a31be09 docs(backend): README with install, CLI, and programmatic usage 2026-06-19 16:01:25 -06:00
Tyler d4f3b204ef feat(backend): click CLI for parse-837 2026-06-19 16:00:47 -06:00
Tyler f1e86979f8 feat(backend): per-claim JSON writer + summary.json 2026-06-19 15:56:09 -06:00
Tyler 2d509d92f4 test(backend): multi-claim CO Medicaid fixture + integration test 2026-06-19 15:54:46 -06:00
Tyler 1f7cb11fd5 feat(backend): 837P parser orchestrator with HL walker 2026-06-19 15:52:58 -06:00
Tyler 1cab95ffc3 feat(backend): structural + CO Medicaid validation rules 2026-06-19 15:45:17 -06:00
Tyler 9db793c108 test(backend): add minimal 837P fixture 2026-06-19 15:42:04 -06:00
Tyler bb35ecd40c feat(backend): PayerConfig with co_medicaid and generic factories 2026-06-19 15:40:09 -06:00
Tyler aa801805ce feat(backend): Pydantic v2 models for 837P claims 2026-06-19 15:39:08 -06:00
Tyler 8475e672a7 feat(backend): X12 segment tokenizer with ISA delimiter detection 2026-06-19 15:36:01 -06:00
Tyler 760d031535 fix(backend): make parsers __init__ re-exports lazy via __getattr__ 2026-06-19 15:32:26 -06:00
Tyler 260b32afac feat(backend): add CycloneParseError and CycloneValidationError 2026-06-19 15:31:06 -06:00
Tyler ce7fb50e79 feat(backend): scaffold cyclone package skeleton 2026-06-19 15:26:52 -06:00