Skip to content

Instantly share code, notes, and snippets.

@tripolskypetr
Last active December 22, 2025 08:55
Show Gist options
  • Select an option

  • Save tripolskypetr/c0d5d423f0d83b55f085404c354c04d4 to your computer and use it in GitHub Desktop.

Select an option

Save tripolskypetr/c0d5d423f0d83b55f085404c354c04d4 to your computer and use it in GitHub Desktop.
FX Cache Demo - Демонстрация критических проблем в финансовых системах

FX Cache Demo - Демонстрация критических проблем в финансовых системах

Этот проект воспроизводит три критические уязвимости в системе обработки курсов валют и банковского клиринга, которые приводят к финансовым потерям и проблемам производительности.

Проблема 1: Устаревшие курсы валют без кеширования

Описание проблемы

При сбое внешнего API курсов валют (HTTP 429, timeout и т.д.) система использует устаревшие хардкоженные курсы из fallback-логики вместо кешированных актуальных значений. Это приводит к значительным финансовым потерям.

Критические проблемы:

  • USD/RUB = 79.35 вместо актуального ~95-100 (потери ~17%)
  • Для неизвестных валютных пар возвращается курс 1.0 (катастрофа!)
  • Отсутствует валидация корректности курсов перед использованием

Задание для кандидата

  1. Реализовать кеширование курсов валют в базу данных с timestamp

    • Если API недоступно, использовать значение из кеша (если обновлено < 1 часа)
    • Добавить валидацию корректности курса перед сохранением
    • Создать политику повторных попыток получения курса
  2. Добавить проверку на взлом/некорректные данные от стороннего API

    • Если курс выглядит статистически невалидным (например, 1:1), отклонить транзакцию
    • Реализовать fallback логику с уведомлением администратора
  3. Интегрировать реальное внешнее API на выбор:

Проблема 2: Race Condition при банковском клиринге

Описание проблемы

Отсутствие уникального индекса на ключе идемпотентности создает race condition при одновременных запросах, что приводит к дублированию платежей. Два платежа вместо одного, двойное списание денег.

Задание для кандидата

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

  • Обработать исключение нарушения уникальности (duplicate key exception)
  • При возникновении конфликта вернуть результат существующей транзакции
  • Использовать правильную транзакционную изоляцию

Проблема 3: Отсутствие пагинации - загрузка всех данных в память

Описание проблемы производительности

Метод findAll() загружает ВСЕ записи из базы данных в память, а фильтрация выполняется на стороне приложения вместо SQL WHERE clause. Загрузили 2.5 GB данных и 30 секунд обработки, чтобы вернуть 10 KB!

Задание для кандидата

Переработать реализацию так, чтобы фильтрация и пагинация выполнялись на уровне базы данных.

Дополнительные задания

  1. Производительность: Создать k6 тесты, посчитать RPS на основе объективных данных

  2. Безопасность: Создать batch эндпоинт для импорта транзакций из excel. Внедрить модуль антивируса для проверки загружаемых файлов

API Endpoints:

Проблема 1 (Курсы валют):

  • GET /api/fx/rate?from=USD&to=RUB - Получить курс валюты (устаревшие fallback курсы)

Проблема 2 (Идемпотентность):

  • POST /api/clearing/process - Обработать клиринговую транзакцию
  • GET /api/clearing/duplicates?idempotencyKey=XXX - Проверить дубликаты
  • DELETE /api/clearing/all - Очистить все транзакции

Проблема 3 (Производительность):

  • GET /api/reports/transactions?daysBack=7&limit=20 - Получить отчет (проблемная реализация)
  • GET /api/reports/partner/{partnerId}?limit=10 - Транзакции партнера (проблемная реализация)
  • GET /api/reports/stats - Статистика по БД
@tripolskypetr

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment