docs(sp37): document canonical submit-batch flow
RUNBOOK gets a 'Submitting claims (canonical)' section with both CLI and HTTP examples, the shared cyclone.submission.submit_file helper, and a 'submit-batch vs resubmit-rejected-claims' decision rule. CLAUDE.md gets a pointer to cyclone/submission/ in the 'Backend at a glance' subpackage list.
This commit is contained in:
@@ -125,7 +125,7 @@ Frontend triplet for any live page: `use<X>(params)` (initial fetch) + `useTailS
|
|||||||
|
|
||||||
## Backend at a glance
|
## Backend at a glance
|
||||||
|
|
||||||
`backend/src/cyclone/` is a single namespace. The two largest files are `api.py` (~3,548 LOC, the only large file) and `store.py` (~2,423 LOC, the `CycloneStore` facade — SP21 is in flight to split it into a `cyclone/store/` subpackage; the public API stays unchanged). Subpackages: `api_routers/` (acks, admin, health, ta1_acks), `clearhouse/` (Clearhouse + SftpClient), `edi/` (filenames), `parsers/` (X12 transaction parsers + models + validators + serializers), `workflow/` (placeholder for future sub-project 6).
|
`backend/src/cyclone/` is a single namespace. The two largest files are `api.py` (~3,548 LOC, the only large file) and `store.py` (~2,423 LOC, the `CycloneStore` facade — SP21 is in flight to split it into a `cyclone/store/` subpackage; the public API stays unchanged). Subpackages: `api_routers/` (acks, admin, health, ta1_acks), `clearhouse/` (Clearhouse + SftpClient), `edi/` (filenames), `parsers/` (X12 transaction parsers + models + validators + serializers), `submission/` (SP37 — canonical `submit_file` helper shared by `cyclone submit-batch` CLI + `POST /api/submit-batch` HTTP endpoint; owns parse → DB-write → SFTP-upload → audit per file), `workflow/` (placeholder for future sub-project 6).
|
||||||
|
|
||||||
The store is the only read/write surface for the database; every mutating endpoint goes through it. All persistence flows through SQLAlchemy sessions via `db.SessionLocal()()`. SQLAlchemy ORM models live in `db.py`; 12 SQL migrations under `migrations/` (0001_initial through 0012_backups) are walked in order by `db_migrate.py`.
|
The store is the only read/write surface for the database; every mutating endpoint goes through it. All persistence flows through SQLAlchemy sessions via `db.SessionLocal()()`. SQLAlchemy ORM models live in `db.py`; 12 SQL migrations under `migrations/` (0001_initial through 0012_backups) are walked in order by `db_migrate.py`.
|
||||||
|
|
||||||
|
|||||||
@@ -187,6 +187,52 @@ absent.)
|
|||||||
`processed_inbound_files` are skipped automatically — to re-process,
|
`processed_inbound_files` are skipped automatically — to re-process,
|
||||||
delete the row first (`DELETE FROM processed_inbound_files WHERE name = ...`).
|
delete the row first (`DELETE FROM processed_inbound_files WHERE name = ...`).
|
||||||
|
|
||||||
|
### Submitting claims (canonical — SP37)
|
||||||
|
|
||||||
|
For 837P files generated upstream (dzinesco) that you want cyclone to
|
||||||
|
**track in the DB** before uploading, use the canonical submit path.
|
||||||
|
This is the preferred outbound path going forward — it captures the
|
||||||
|
batch's `transaction_set_control_number` (the ST02 control number that
|
||||||
|
999 acks reference in AK201) so future 999 ack links resolve instead
|
||||||
|
of becoming orphans.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/tyler/dev/cyclone/backend
|
||||||
|
|
||||||
|
# 1. Lay out files in batch-*-claims subdirs under your ingest dir:
|
||||||
|
# ingest/batch-2026-07-08-claims/claim-001.x12
|
||||||
|
# ingest/batch-2026-07-08-claims/claim-002.x12
|
||||||
|
# ...
|
||||||
|
|
||||||
|
# 2. CLI — walks ingest/, parses, writes to DB, then SFTP-uploads.
|
||||||
|
.venv/bin/python -m cyclone submit-batch \
|
||||||
|
--ingest-dir /home/tyler/dev/cyclone/ingest \
|
||||||
|
--actor cli-submit-batch
|
||||||
|
|
||||||
|
# Or via HTTP (auth-gated by matrix_gate):
|
||||||
|
curl -s -X POST http://localhost:8000/api/submit-batch \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{"ingest_dir": "/home/tyler/dev/cyclone/ingest", "actor": "api-submit-batch"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Both surfaces share `cyclone.submission.submit_file` for the
|
||||||
|
parse → DB-write → SFTP-upload chain (DB-first, upload-second
|
||||||
|
invariant). The walker pattern is identical: `batch-*-claims/*.x12`,
|
||||||
|
sorted, with `._*` AppleDouble files skipped.
|
||||||
|
|
||||||
|
**When to use `submit-batch` vs `resubmit-rejected-claims`:**
|
||||||
|
- `submit-batch` — canonical path for fresh 837s from dzinesco (or any
|
||||||
|
source) that should be tracked in the DB before upload. Default choice.
|
||||||
|
- `resubmit-rejected-claims` — one-off path for cases where you do NOT
|
||||||
|
want a DB row (e.g., dzinesco-generated fixes not ready for canonical
|
||||||
|
tracking). Legacy, retained for backward compat.
|
||||||
|
|
||||||
|
**Status codes / exit codes:**
|
||||||
|
- HTTP 200 on completed runs (per-file failures live in the JSON body);
|
||||||
|
401 unauthenticated; 404 no clearhouse; 409 stub mode; 422 validation.
|
||||||
|
- CLI exit 0 on completed runs (per-file failures counted, not bumped);
|
||||||
|
2 on config-level failures (no clearhouse / stub mode / missing dir).
|
||||||
|
|
||||||
### Note on per-file parse CLIs
|
### Note on per-file parse CLIs
|
||||||
|
|
||||||
`parse-837` and `parse-835` exist as CLIs but only emit JSON files to
|
`parse-837` and `parse-835` exist as CLIs but only emit JSON files to
|
||||||
|
|||||||
Reference in New Issue
Block a user