Skip to content

Архитектура хранения долга и начисления пеней

Источник: ранее файл Инструкции/DEBT_AND_PENALTY_ARCHITECTURE.md (перенесён и стандартизирован).

Документ описывает, как Nimbus хранит долг по лицевым счетам, как рассчитываются и применяются пени в соответствии с ПП 354, и как это связано с Ledger‑архитектурой и миграциями данных.

📋 Требования к функционалу

Основные требования

  1. Хранение долга по лицевым счетам:

    • долг должен храниться с привязкой к начислениям (Billing);
    • нужна история долга;
    • нужна возможность отслеживания источников долга.
  2. Начисление пеней:

    • пени начисляются только на сумму начисления (не на всю сумму долга);
    • первые 30 дней просрочки — льготный период без пеней;
    • с 31‑го по 90‑й день: 1/300 ставки за день;
    • с 91‑го дня: 1/130 ставки за день;
    • пени начисляются на основной долг + предыдущие пени, но не на сами пени (ретроспективно).
  3. Учёт ставки рефинансирования:

    • до 1 января 2027 г.: минимум 9,5% (ставка на 27.02.2022) или актуальная ключевая ставка;
    • с 1 января 2027 г.: применяется текущая ключевая ставка;
    • ставка берётся на день оплаты или день расчёта пеней.

🏗️ Архитектура хранения долга

Документ подробно описывает следующие модели и их роли:

  • AccountBalance — агрегированный баланс по лицевому счёту (principalDebt, penaltyDebt, totalDebt);
  • DebtItem — долг, привязанный к конкретному начислению (период, сумма, даты наступления просрочки и начала начисления пеней);
  • PenaltyCalculation — история расчётов пеней (период, ставка, количество дней, расчётная сумма);
  • InterestRate — справочник ставок ЦБ РФ с возможностью получения актуальной ставки на дату.

Модели приведены на Go и в SQL‑миграциях, чтобы разработчик мог сразу встроить их в billing-service.

📊 Логика расчёта пеней

Основные блоки логики:

  • функция CalculatePenalty — рассчитывает пени для одного DebtItem на дату:
    определяет период, тип ставки (1/300 или 1/130), учитывает льготу 9,5% до 2027 года и вычисляет сумму пеней;
  • функция GetInterestRateForCalculation — получает ставку для расчёта пеней с учётом льгот;
  • функция ApplyPenaltyToDebt — применяет рассчитанные пени к долгу и обновляет AccountBalance;
  • функция CalculatePenaltiesForAllOverdueDebts — массовый расчёт пеней для всех просроченных долгов.

В документе приведён подробный Go‑код с комментариями и SQL‑миграциями, которые можно использовать как эталонную реализацию.

🔄 Процесс применения начисления и оплаты к долгу

При принятии начисления (Billing)

  • функция ApplyBillingToDebt:
    • создаёт (или обновляет) DebtItem по каждому ЛС в рамках расчётного периода (Billing);
    • рассчитывает DueDate, FirstOverdueDate, PenaltyStartDate;
    • обновляет AccountBalance (увеличивает PrincipalDebt и TotalDebt).

При оплате (списание с долга)

  • функция ApplyPaymentToDebt:
    • применяет платеж к долгам по правилу FIFO (сначала старые долги);
    • сначала гасит пени, затем основной долг;
    • пересчитывает агрегированный баланс по ЛС.

📅 Планировщик расчёта пеней

Рекомендуется использовать планировщик (например, cron) для ежедневного перерасчёта пеней:

  • раз в сутки запускать CalculatePenaltiesForAllOverdueDebts;
  • логировать ошибки и результаты для аудита.

В документе приведён пример функции SchedulePenaltyCalculation на Go.

🔧 Миграции БД

Раздел содержит SQL‑миграции для таблиц:

  • account_balances;
  • debt_items;
  • penalty_calculations;
  • interest_rates.

А также индексы, необходимые для эффективного поиска по ЛС, периодам и датам.

👤 Архитектура собственника лицевого счёта

В финальной части документа описана архитектура сущности Owner и её связь с PersonalAccount:

  • выделение собственника в отдельную таблицу owners;
  • обновление модели PersonalAccount с полем OwnerID;
  • миграция данных из старой схемы (когда данные собственника хранились прямо в PersonalAccount);
  • рекомендации по CRUD‑формам для собственников в UI, API‑эндпоинтам и структуре фронтенда.

Импорт данных из системы Квадо

Заключительный большой блок описывает стратегию импорта задолженностей и пеней из легаси‑системы (Квадо):

  • несколько вариантов переносов (минимальный, расширенный на 3–6 месяцев, полный);
  • рекомендации по распределению агрегированных пеней по периодам;
  • проверка совпадения балансов после импорта;
  • стратегии работы с неполными или неточными данными.

Этот раздел служит практическим гайдом по миграции долгов в Nimbus с сохранением корректного расчёта пеней в будущем.