Files
finance/docs/parsers/private-fixture-gate.md
T
k1nq e43428c1a2
Gitea Actions CI / detect (push) Successful in 3s
Gitea Actions CI / Compose & nginx validation (push) Failing after 20s
Gitea Actions CI / Frontend (lint / type / test / build) (push) Failing after 24s
Gitea Actions CI / Backend (lint / type / test / build) (push) Failing after 1m34s
Implement Gitea CI and real statement imports
2026-09-18 17:59:02 +05:00

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_DIR or the ignored repository-local examples/ directory, never in Git and never in shared storage without encryption.

  • Each private fixture directory contains an ignored manifest.json beside 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_fixtures
    

    When PRIVATE_FIXTURES_DIR is unset, the suite may use the ignored repository-local examples/ 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.