Финансовые сверки и доказательство корректности данных
Почему равенство сумм недостаточно, как устроить многоуровневую проверку и воспроизводимое расследование расхождений.
3 мин чтения·База знаний
Справочный материал. Контракты данных, архитектурные решения и ограничения применения. Источники приведены в материалах, где используются внешние основания.
Когда итоговые суммы источника и EDWH совпали, проверка ещё не завершена. Нужно разделять:
Полноту: всё ли, что должно было прийти, действительно загружено?
Точность: совпадают ли значения и атрибуты каждой сопоставленной записи?
Согласованность: не нарушены ли финансовые ограничения и связи между сущностями?
Эти свойства логически независимы. Можно получить правильный общий итог при двух компенсирующих ошибках либо загрузить все записи с неверными атрибутами.
Для сравнения самостоятельных учётных представлений двух компаний используйте парную межфирменную сверку: она проверяет встречные требования и обязательства, а не доставку копии набора событий.
Пусть в источнике два документа: +100 и −100. Оба исчезли на этапе загрузки. Сумма источника равна нулю, сумма приёмника тоже ноль, но загрузка неполная.
Поэтому сверку лучше формулировать как задачу сравнения множеств событий и их свойств, а уже затем агрегатов.
source_ids = {id | id должен войти в этот срез}
target_ids = {id | id действительно представлен}
missing = source_ids - target_ids
extra = target_ids - source_ids
Следом сравниваем канонические содержимое и версии по каждому id.
Для каждого загруженного события ровно две строки журнала: одна дебетовая, одна кредитовая (частное правило учебного стенда).
Обе строки относятся к одной валюте и равной денежной величине.
Подписанная сумма по событию равна нулю.
Повторный импорт идентичного пакета не увеличивает число событий или строк.
Событие с тем же ID, но иной полезной нагрузкой отклоняется, а не молча перезаписывается.
Срез на историческую дату отличается от пересчитанного после поздней коррекции.
В промышленной модели часть этих правил должна быть адаптирована к реальной структуре проводок: запись может содержать больше двух строк, несколько валютных сумм и особые учётные контуры.
Корректный результат проверки - не просто PASS/FAIL. Полезно сохранять: ID контрольного набора, входной batch, бизнес-срез, системный срез, правило, число нарушений, идентификаторы проблемных записей и версию кода преобразований.
Для массовых загрузок стоит разделять ошибки источника и ошибки обработки. Если входной документ уже несбалансирован, задача EDWH - явно обнаружить и корректно зарегистрировать проблему, а не создать баланс путём скрытого исправления.
Matching source and EDWH totals do not complete a reconciliation. Separate these questions:
Completeness: did everything that should have arrived actually load?
Accuracy: do values and attributes match for each corresponding record?
Consistency: are financial constraints and entity relationships valid?
These properties are logically independent. Two offsetting errors can produce a correct total, or every record can load with incorrect attributes.
For two independent accounting representations, use pairwise intercompany reconciliation: it compares reciprocal receivables and payables rather than delivery of a copied event set.
Suppose the source has two documents, +100 and −100. Both disappear during loading. The source total is zero and the target total is also zero, but the load is incomplete.
Reconciliation should first compare sets of events and their properties, then compare aggregates.
source_ids = {id | id should be included in this snapshot}
target_ids = {id | id is actually present}
missing = source_ids - target_ids
extra = target_ids - source_ids
Next compare canonical content and versions for each id.
Every loaded event has exactly two journal lines: one debit and one credit (a lab-specific rule).
Both lines use the same currency and equal monetary amounts.
The signed sum per event is zero.
Reimporting an identical package does not increase the number of events or lines.
An event with the same ID but a different payload is rejected, not silently overwritten.
A historical snapshot differs from the recalculated result after a late correction.
A production model must adapt some rules to its actual journal structure: an entry may contain more than two lines, multiple currency amounts, and specialized ledgers.
A useful check result is more than PASS/FAIL. Preserve the control-set ID, input batch, business and system snapshots, rule, violation count, problematic record IDs, and transformation-code version.
For bulk loads, distinguish source errors from processing errors. If an input document is already unbalanced, the EDWH should detect and record the issue explicitly, not hide it by manufacturing a balancing entry.
The Financial EDWH Lab contains a small runnable example. Its tests cover repeated loads, ID conflicts, balance, completeness, and late financial corrections. Source code and tests are available as an archive.