Appearance
Архитектура хранения долга и начисления пеней
Источник: ранее файл
Инструкции/DEBT_AND_PENALTY_ARCHITECTURE.md(перенесён и стандартизирован).
Документ описывает, как Nimbus хранит долг по лицевым счетам, как рассчитываются и применяются пени в соответствии с ПП 354, и как это связано с Ledger‑архитектурой и миграциями данных.
📋 Требования к функционалу
Основные требования
Хранение долга по лицевым счетам:
- долг должен храниться с привязкой к начислениям (Billing);
- нужна история долга;
- нужна возможность отслеживания источников долга.
Начисление пеней:
- пени начисляются только на сумму начисления (не на всю сумму долга);
- первые 30 дней просрочки — льготный период без пеней;
- с 31‑го по 90‑й день: 1/300 ставки за день;
- с 91‑го дня: 1/130 ставки за день;
- пени начисляются на основной долг + предыдущие пени, но не на сами пени (ретроспективно).
Учёт ставки рефинансирования:
- до 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 с сохранением корректного расчёта пеней в будущем.