2.9 KiB
Parser Private Fixture Gate
Real bank statements contain personal financial data and are never committed
to Git. CI runs synthetic fixtures only. Private fixtures may live either in an
external directory or in the ignored repository-local examples/ directory.
Contract
-
Synthetic parser inputs live with the backend tests and run in CI.
-
Real statement files stay in
PRIVATE_FIXTURES_DIRor the ignored repository-localexamples/directory, never in Git and never in shared storage without encryption. -
Each private fixture directory contains an ignored
manifest.jsonbeside the statements. For each fixture it records the filename, adapter ID, parser version, period, row counts, control totals, balances, and HOLD totals. -
The manifest and its expected values are private financial data. They must not appear in tracked test parameters, documentation, CI inputs, artifacts, or logs.
-
Private assertions report only a filename, adapter ID, dates, counts, and the name of a mismatched aggregate. They never render parsed rows, descriptions, names, account/card numbers, extracted pages, or expected financial values.
-
The private suite runs explicitly, on the developer's machine:
PRIVATE_FIXTURES_DIR=/secure/path/fixtures uv run pytest -m private_fixturesWhen
PRIVATE_FIXTURES_DIRis unset, the suite may use the ignored repository-localexamples/directory. The dedicated marker keeps this suite out of normal CI collection.
Beta gate per adapter/contract
An adapter may be declared beta-supported only when, against private fixtures:
- at least two complete real periods of its contract parse successfully;
- malformed file fails with stable diagnostics (no crash, no partial state);
- oversized file is rejected by quotas before parsing;
- duplicate statements produce identical parse results (hash-idempotent enqueue/apply);
- overlapping periods produce expected duplicate candidates for review, not silent merges;
- wrong-bank/encrypted/scanned (no text layer) files are detected and refused.
Record the gate result per adapter version below. An adapter without a passed gate must not be enabled or advertised, even if synthetic tests pass (plan §"Основные риски и gates").
Gate status
| Adapter / parser version | Private periods passed | Gate |
|---|---|---|
| Alfa debit XLSX / 2 | 1 | not passed |
| Alfa credit XLSX / 1 (unregistered) | 0 | not passed |
| Ozon debit PDF / 2 | 1 | not passed |
| Ozon credit PDF / 1 (unregistered) | 0 | not passed |
| Rocketbank debit PDF / 2 | 1 | not passed |
The three debit contracts each pass one local private fixture deterministically, but no adapter is currently gated. A second independent real period/layout is still required for each contract. Bank layout drift resets the gate: it must create a new parser version and a review diff, never reinterpret historical data.