Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Аудит денежных операций

Аудит денежных операций: журнал, неизменяемость и проверка

Аудит денежных операций: журнал изменений, неизменяемые записи, хранение состояния до и после и проверка расхождений.

Прямой ответ

Журнал денежных операций фиксирует каждое изменение суммы вместе с состоянием до и после, поэтому расхождение выявляется по записям журнала, а не по текущему значению.

Параметр аудита Что определяет
Запись журнала Факт операции с суммой и временем
Состояние до и после Значение до изменения и после
Неизменяемость Запрет изменения и удаления записи
Автор операции Идентификатор инициатора изменения
CREATE TABLE audit_log (
  id BIGSERIAL PRIMARY KEY,
  account_id BIGINT NOT NULL,
  amount NUMERIC(19,2) NOT NULL,
  balance_before NUMERIC(19,2) NOT NULL,
  balance_after NUMERIC(19,2) NOT NULL,
  actor TEXT NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
REVOKE UPDATE, DELETE ON audit_log FROM app_user;

Запись журнала содержит значение до и после изменения, поэтому расхождение баланса определяется сравнением последовательных записей. О списании — в статье про денежные операции в БД.

Запись журнала и состав полей

Запись журнала фиксирует факт операции, поэтому состав полей определяет, можно ли восстановить последовательность изменений.

Сумма операции. Значение изменения фиксируется в записи, поэтому величина операции воспроизводится без обращения к текущему состоянию.

Состояние до и после. Значение баланса до изменения и после фиксируются, поэтому последовательность изменений проверяется сравнением соседних записей.

Время и автор. Момент операции и идентификатор инициатора фиксируются, поэтому ответственность за изменение определяется.

Практическое следствие: журнал без состояния до и после не позволяет проверить непрерывность изменений, поэтому расхождение не локализуется до конкретной операции.

Отдельный аспект — связь записи с операцией. Запись журнала ссылается на операцию, поэтому изменение, не отражённое в журнале, обнаруживается по отсутствию ссылки.

Неизменяемость журнала

Неизменяемость журнала исключает изменение и удаление записей, поэтому история операций не может быть скорректирована задним числом.

Запрет изменения. Права на изменение и удаление записей журнала отзываются, поэтому запись не корректируется после создания.

Добавление вместо изменения. Корректировка выполняется новой записью, поэтому последовательность изменений сохраняется.

Проверка прав. Права на таблицу журнала проверяются, поэтому изменение записи приложением исключается.

Практическое следствие: журнал с правом изменения записей не подтверждает историю операций, поскольку запись может быть скорректирована задним числом.

Проверка расхождений

Проверка расхождений сравнивает журнал с текущим состоянием, поэтому операция, не отражённая в балансе, обнаруживается явно.

Сравнение итога. Сумма записей журнала сравнивается с текущим балансом, поэтому расхождение указывает на операцию, не применённую к балансу.

Непрерывность последовательности. Значение после в записи совпадает со значением до в следующей записи, поэтому пропуск операции обнаруживается.

Локализация расхождения. Сравнение выполняется по счёту, поэтому расхождение локализуется до конкретной операции.

Практическое следствие: расхождение, не обнаруженное регулярной проверкой, остаётся незамеченным до формирования отчётности.

О сверке с внешними источниками — в статье про сверку платежей; о журнале действий — в статье про аудит действий пользователя.

Практика: настройка аудита денежных операций

1. Фиксируйте сумму и состояние до и после в записи. Последовательность изменений проверяется сравнением соседних записей.

2. Записывайте время и автора операции. Ответственность за изменение определяется по записи журнала.

3. Отзовите права на изменение журнала. Запись не корректируется задним числом, поэтому история подтверждается.

4. Выполняйте корректировку новой записью. Последовательность изменений сохраняется, поэтому история не прерывается.

5. Свяжите запись журнала с операцией. Изменение, не отражённое в журнале, обнаруживается по отсутствию ссылки.

6. Настройте регулярную проверку баланса против журнала. Расхождение обнаруживается до формирования отчётности.

7. Проверяйте непрерывность последовательности записей. Пропуск операции обнаруживается по несовпадению значений.

Рекомендации:

  1. Не оставляйте права на изменение журнала приложению. Запись может быть скорректирована, поэтому история не подтверждается.
  2. Учитывайте объём журнала при хранении. Каждая операция добавляет запись, поэтому объём растёт пропорционально числу операций.
  3. Сопоставляйте состав полей с требованием проверки. Журнал без состояния до и после не позволяет локализовать расхождение.
  4. Фиксируйте регулярность проверки согласованности. Расхождение обнаруживается до формирования отчётности.
  5. Пересматриваем состав полей при изменении схемы. Новый параметр операции требует добавления в запись журнала.

Практический сценарий: расхождение баланса не удавалось локализовать

Контекст: баланс счёта расходился с ожидаемым значением, но определить операцию, вызвавшую расхождение, не удавалось.

  1. Диагностика. Проверка показала, что журнал операций содержал только сумму изменения без значения баланса до и после. Последовательность изменений не проверялась, поэтому операция, не применённая к балансу, не обнаруживалась.
  2. Причина. Состав полей журнала не позволял проверить непрерывность последовательности, поэтому расхождение не локализовалось до конкретной операции.
  3. Действия. (а) Добавили в запись журнала значение баланса до и после изменения, чтобы последовательность проверялась сравнением соседних записей; (б) отозвали права на изменение и удаление записей журнала, чтобы история не корректировалась задним числом; (в) связали запись журнала с операцией, чтобы изменение без записи обнаруживалось; (г) настроили регулярную проверку суммы записей журнала против текущего баланса; (д) пересчитали исторические расхождения и локализовали операции, не отражённые в балансе.
  4. Результат. Расхождение локализуется до конкретной операции, поскольку последовательность изменений проверяется по значениям до и после.

Вывод: журнал без значения состояния до и после не позволяет проверить непрерывность последовательности изменений, поэтому расхождение баланса не локализуется. Фиксация обоих значений и регулярная сравнительная проверка делают расхождение обнаружимым.

FAQ

Какие поля обязательны в журнале денежных операций? Сумма изменения, значение баланса до и после, время операции и идентификатор автора. Без состояния до и после последовательность не проверяется.

Зачем запрещать изменение записей журнала? Запись, которую можно скорректировать задним числом, не подтверждает историю операций, поэтому расхождение не обнаруживается.

Как выполнить корректировку при неизменяемом журнале? Новой записью. Последовательность изменений сохраняется, поэтому история не прерывается.

Как обнаружить расхождение баланса? Сравнением суммы записей журнала с текущим балансом и проверкой непрерывности последовательности значений до и после.

Источники: PostgreSQL privileges, PostgreSQL triggers, PostgreSQL numeric types — ссылки в шапке.