Система управления Дебиторкой Задолженностью - Описание проекта
Краткое резюме
Комплексная B2B платформа для управления кредитными лимитами, разработанная для российских производственных и дистрибьюторских компаний. Система автоматизирует весь жизненный цикл кредитной заявки — от первоначальной подачи через многоэтапные согласования отделов, оценку рисков, рассмотрение кредитным комитетом и текущий мониторинг кредитных линий. Построенная на Django с использованием мобильных API для выездной работы, платформа интегрирует внешние источники данных для оценки кредитоспособности и предоставляет уведомления в реальном времени через Firebase Cloud Messaging.
Бизнес-функциональность
1. Основное бизнес-назначение
Система служит централизованной платформой управления кредитными рисками для компаний, которые продают продукцию в кредит бизнес-клиентам. Она заменяет ручные, основанные на таблицах процессы утверждения кредитов структурированным рабочим процессом, который обеспечивает соблюдение корпоративных политик, предоставляет оценку рисков на основе данных и поддерживает полный аудит.
Целевые пользователи:
- Менеджеры по продажам, подающие кредитные заявки
- Специалисты по оценке рисков, оценивающие кредитоспособность
- Директора по кредитам филиалов, утверждающие региональные лимиты
- Члены кредитного комитета, рассматривающие крупные сделки
- Юридические и бухгалтерские отделы, проверяющие соответствие
2. Ключевые бизнес-процессы
Рабочий процесс кредитной заявки
Система обеспечивает многоуровневую цепочку утверждения с автоматической маршрутизацией и уведомлениями:
- Менеджер - Менеджер по продажам создает заявку, вводит основные данные клиента
- Финансы - Финансовая служба проверяет финансовую отчетность, историю платежей
- Юрист - Юридический отдел проверяет условия договоров, гарантии, корпоративную структуру
- Директор филиала (КД Филиала) - Региональный орган утверждения (лимиты до порогового значения)
- Кредитный комитет - Рассмотрение комитетом для крупных кредитных лимитов (>порогового значения)
- Генеральный директор - Утверждение генеральным директором для исключительных/крупных сделок
- Исполнение отлагательных условий - Клиент выполняет требуемые условия (гарантии, документы)
- Проверка отлагательных условий - Юридический отдел проверяет выполнение условий
- Изменение лимита в ERP - Утверждено, ожидается интеграция с ERP
- Снятие лимита в ERP - Удаление аннулированного лимита из ERP
- Открытый лимит - Активная кредитная линия, клиент может совершать покупки в кредит
- Отозванный лимит - Кредит приостановлен из-за проблем с оплатой
- Отказано - Заявка отклонена
- Судебный - Клиент находится в процессе взыскания/судебного разбирательства
Каждый переход статуса создает запись аудита с отметкой времени, пользователем и комментарием.
Оценка кредитного риска
Специалист по рискам использует интегрированные внешние источники данных:
Интеграция с API Контур: Автоматически извлекает данные о российских компаниях:
- Регистрационные данные компании (юридическое название, отрасль, дата регистрации, количество сотрудников)
- Информация о руководстве (имя генерального директора, дата назначения)
- Финансовая отчетность за 3+ года (баланс, отчет о прибылях и убытках)
- Арбитражные судебные дела (анализ ответчика/истца)
- Данные о задолженности Федеральной налоговой службы
- Исполнительные производства (действия судебных приставов)
- Структура акционеров и бенефициарные владельцы
Финансовый анализ: Система хранит и отображает:
- Показатели баланса (активы, капитал, коэффициенты долга)
- Отчет о прибылях и убытках (выручка, EBITDA, чистая прибыль, рентабельность)
- История платежей с компанией (DSO, просроченные счета)
- Ежемесячные тенденции рентабельности
Панель индикаторов риска:
- Количество и суммы активных судебных дел
- Налоговые задолженности, выделенные красным
- Количество исполнительных производств
- Оценка судебного риска на основе "кто на них подает в суд"
Процесс запроса на превышение лимита
Когда менеджеру по продажам необходимо обработать заказ, превышающий утвержденный кредитный лимит клиента:
- Менеджер подает запрос на превышение лимита с обоснованием, суммой заказа, данными счета
- Система рассчитывает сумму превышения лимита (общая сумма счета - доступный кредит)
- Запрос автоматически направляется:
- Кредитному директору филиала (для меньших сумм)
- Кредитному комитету (для больших сумм)
- Утверждающий рассматривает историю клиента, текущую задолженность, платежную дисциплину
- Утверждение/отклонение создает запись аудита (OverLimitResponsibility) с именем утверждающего
- Менеджер получает push-уведомление о решении
Управление просроченной задолженностью
Система отслеживает просроченную дебиторскую задолженность на уровне транзакций:
- Просрочка по документам: Каждый просроченный счет отслеживается отдельно (номер документа, сумма, количество дней просрочки)
- Комментарии по сбору задолженности: Отдельный поток комментариев для действий по сбору задолженности
- Автоматические уведомления: Оповещает менеджеров, когда клиенты просрочивают платежи
- Эскалация: Постоянное невыполнение платежей вызывает изменение статуса на "Судебный"
- Панель просроченной задолженности: Просмотр общей суммы просроченной задолженности по отделам, анализ сроков
Управление договорами и документацией
Для каждой утвержденной кредитной заявки:
- Договор: Хранит условия кредитного соглашения (процентная ставка по кредиту, процентная ставка по пени, условия оплаты, требуемые гарантии)
- Поручительства: Договоры личного поручительства с отдельными поручителями
- Документы: Загрузка файлов (финансовая отчетность, налоговые справки, устав компании, гарантийные письма)
- Генерация документов: Система может генерировать повестки дня кредитного комитета, протоколы утверждения
Операции кредитного комитета
- Планирование заседаний: Кредитный комитет собирается по установленному графику
- Управление повесткой дня: Заявки, поданные в комитет, автоматически ставятся в очередь
- Запись решений: Члены комитета записывают решения, условия, особые условия
- Электронная рассылка: Повестки дня и протоколы рассылаются членам комитета по электронной почте
Операции в нескольких филиалах/отделах
Система позволяет настроить разные филиалы, например:
- МСК (Москва)
- СПБ (Санкт-Петербург)
- ТГН (Таганрог)
- СМР (Самара)
- СРТ (Саратов)
- КРД (Краснодар)
- ПРОЕКТЫ (Проекты)
Каждый филиал имеет:
- Своих менеджеров по продажам и директора по кредитам филиала
- Портфель клиентов и кредитные лимиты
- Панель управления, показывающую показатели филиала
3. Мобильные выездные операции (приложение SWIFT)
Бизнес-ценность: Менеджерам по продажам на выезде необходим мгновенный доступ к кредитному статусу клиента во время посещения клиентов.
Мобильные возможности:
- Данные в реальном времени: Просмотр текущего кредитного лимита, задолженности, просроченных сумм, статуса заявки
- Финансовый анализ: Доступ к балансу, отчету о прибылях и убытках на мобильном устройстве
- Действия в рабочем процессе: Утверждение/отклонение заявок с мобильного устройства
- Коммуникация: Добавление комментариев, просмотр веток обсуждений
- Push-уведомления: Мгновенные оповещения об изменениях статуса, решениях кредитного комитета, комментариях
- Готовность к работе в автономном режиме: Мобильное приложение может кэшировать данные для выездных зон с плохим соединением
- Поддержка нескольких компаний: Мобильный API поддерживает развертывание для нескольких компаний (inoxtrade.ru, ariel.ru и т. д.) с отдельными базами данных для каждой компании.
- Настройки уведомлений: Пользователи настраивают, какие изменения статуса вызывают push-уведомления (фильтр на основе JSON для каждого устройства).
4. Управление подписками и платежами (приложение Users)
Модель SaaS-бизнеса:
- Тарифные планы: Цены основаны на количестве юридических лиц, которыми управляет компания (250, 500, 1000, 1500, 2000, 3000)
- Периоды выставления счетов: Ежемесячные или ежегодные подписки
- Интеграция с YooKassa: Платежный шлюз для российского рынка
- Запросы на демо: Форма генерации лидов вызывает автоматическое последующее действие
- Поддержка нескольких компаний: Приложение позволяет одному пользователю получать доступ к нескольким экземплярам компании
5. Система уведомлений и связи
Комплексная маршрутизация уведомлений:
- Уведомления об изменении статуса: Автоматические оповещения, когда заявка переходит в отдел пользователя
- Уведомления о комментариях: Оповещение упомянутых пользователей или заинтересованных сторон заявки
- Уведомления о превышении лимита: Мгновенные push-уведомления утверждающим
- Уведомления кредитного комитета: Распределение повестки дня
- Оповещения о просроченной задолженности: Предупреждение, когда клиенты просрочивают платежи
Каналы уведомлений:
- Центр уведомлений в приложении (значок колокольчика со счетчиком)
- Уведомления по электронной почте
- Мобильные push-уведомления (Firebase)
- Обновления в реальном времени по WebSocket (Django Channels)
Предпочтения пользователя: Пользователи контролируют частоту, типы и каналы доставки уведомлений.
Архитектура кода
1. Стек технологий
Фреймворк бэкенда
- Django 4.2.6: Основной веб-фреймворк
- Django REST Framework: RESTful API для мобильного приложения
- Django Channels: Поддержка WebSocket для функций реального времени
- Django Tables2: Расширенная отрисовка таблиц с сортировкой/фильтрацией
- Django Filters: Комплексная фильтрация запросов
- Django Crispy Forms: Отрисовка форм с использованием Bootstrap
База данных
- PostgreSQL: Основная база данных
- Схема: Более 39 моделей в 3 приложениях, сложные отношения
Кэширование и обмен сообщениями
- Redis 7.2.4:
- Бэкенд Django Channels (соединения WebSocket)
- Хранение сессий
- Бэкенд кэша
- Защищено паролем
Внешние интеграции
- Kontur API: Российский поставщик бизнес-данных (реестр компаний, финансовые данные, судебные дела)
- Firebase Cloud Messaging (FCM): Push-уведомления для iOS/Android
- YooKassa: Обработка платежей (российский платежный шлюз)
Фронтенд
- Bootstrap 4: CSS-фреймворк
- jQuery: Библиотека JavaScript
- Шаблоны Django: Серверный рендеринг
- Select2: Расширенные выпадающие списки
- Chart.js: Финансовые графики
Развертывание
- Docker Compose: Оркестрация контейнеров
- Nginx: Обратный прокси, завершение SSL
- Gunicorn: Сервер приложений WSGI
- Daphne: Сервер ASGI для Django Channels
- Promtail: Агрегация логов для Grafana
- Node Exporter: Метрики Prometheus
Мониторинг и аналитика
- Django Prometheus: Промежуточное ПО для метрик
- Grafana Promtail: Отправка логов
2. Структура проекта
Credit_Public/
├── clients/ # Управление основными кредитными заявками
│ ├── models.py # Более 39 моделей
│ ├── views.py # Бизнес-логика
│ ├── helpers.py # Интеграция с Kontur API
│ ├── urls.py # Маршрутизация URL
│ ├── serializers.py # DRF сериализаторы
│ ├── tables.py # Определения Django Tables2
│ ├── filters.py # Django Filters
│ ├── forms.py # Определения форм
│ └── admin.py # Кастомизация админки Django
│
├── swift/ # Мобильный API и push-уведомления
│ ├── models.py # Регистрация устройств, настройки уведомлений
│ ├── views.py # Конечные точки мобильного API
│ ├── urls.py # Маршрутизация API
│ ├── serializers.py # Сериализаторы мобильных данных
│ └── consumers.py # Консьюмеры WebSocket (Django Channels)
│
├── users/ # Аутентификация и управление подписками
│ ├── models.py # Модели пользователя, компании, тарифа, платежей
│ ├── views.py # Потоки аутентификации, обработка платежей
│ ├── helpers.py # Интеграция с YooKassa
│ ├── forms.py # Формы регистрации, входа
│ └── urls.py # Маршрутизация URL аутентификации
│
├── django_project/ # Конфигурация Django
│ ├── settings.py # Основные настройки (безопасность, база данных, промежуточное ПО)
│ ├── urls.py # Конфигурация корневого URL
│ ├── asgi.py # Конфигурация ASGI (маршрутизация WebSocket)
│ └── wsgi.py # Конфигурация WSGI
│
├── static/ # Статические ресурсы
│ ├── css/ # Пользовательские таблицы стилей
│ ├── js/ # Файлы JavaScript
│ └── images/ # Ресурсы изображений
│
├── Documents/ # Загруженные пользователем файлы
│ ├── client_files/ # Документы договоров, финансовая отчетность
│ └── logs/ # Логи приложения
│
├── conf/ # Конфигурация Nginx
│ └── conf.d/ # Конфигурации виртуальных хостов, SSL
│
├── requirements.txt # Зависимости Python
├── docker-compose.yml # Оркестрация контейнеров (5 сервисов)
├── Dockerfile # Определение контейнера приложения Django
├── manage.py # CLI для управления Django
├── robots.txt # Конфигурация SEO
└── README.md # Документация проекта
3. Архитектура модели данных
Приложение Clients - Основные модели (clients/models.py)
Основная сущность:
ClientsModel
├── id (PK)
├── client_name (CharField, max_length=500)
├── client_inn (CharField, 12 chars, российский ИНН)
├── client_kpp (CharField, 9 chars, налоговый код филиала)
├── client_debt (DecimalField, текущая сумма долга)
├── client_late_debt (DecimalField, сумма просроченной задолженности)
├── current_limit (DecimalField, утвержденный кредитный лимит)
├── asking_limit (DecimalField, запрашиваемый кредитный лимит)
├── status (ForeignKey → StatusModel, текущий этап рабочего процесса)
├── department (ForeignKey → Department, ответственный филиал)
├── manager (ForeignKey → Employees, менеджер по работе с клиентами)
├── director (ForeignKey → Employees, директор филиала)
└── created_date (DateTimeField, auto_now_add)
Модели рабочего процесса:
- StatusModel: 15 статусов с отображаемыми именами, логикой маршрутизации к следующему статусу
- StatusHistory: Журнал аудита (клиент, старый_статус, новый_статус, пользователь, отметка_времени, комментарий)
- ClientCreditComments: Ветки обсуждений (клиент, пользователь, текст, дата_создания, статус_уведомления)
- CommentsNotifications: Отслеживание прочтения уведомлений для конкретного пользователя
- StatusNotification: Отслеживание доставки уведомлений об изменении статуса
Модели финансовых данных:
- ClientFinances: Агрегированные метрики (общие_активы, собственный_капитал, долг, выручка, прибыль, процент_рентабельности)
- ClientIncomeSt: Статьи отчета о прибылях и убытках (выручка, себестоимость_товаров, валовая_прибыль, операционные_расходы, EBITDA, чистая_прибыль)
- ClientBalanceSt: Статьи баланса (оборотные_активы, основные_средства, краткосрочные_обязательства, долгосрочные_обязательства, капитал)
- ClientPaymentHistory: Исторические платежные транзакции (документ, сумма, дата, срок платежа)
- ClientProfitabilityMonthly: Ежемесячное отслеживание рентабельности по клиенту
Модели внешних данных (Kontur API):
- ClientKonturData: Регистрация компании (полное_название, краткое_название, отрасль, дата_регистрации, имя_руководителя, количество_сотрудников)
- ClientTrials: Судебные дела (название_суда, номер_дела, истец/ответчик, сумма, решение)
- ShareHolders: Структура собственности (имя_акционера, процент_доли, тип)
- DefendantCourts: Анализ истца для оценки судебного риска
- Monitoring: Мониторинг налоговой задолженности (сумма_налоговой_задолженности, источник, дата_последней_проверки)
Модели договоров и документов:
- ClientContract: Условия кредитного соглашения (номер_договора, процентная_ставка_кредита, процентная_ставка_пени, условия_оплаты, тип_гарантии, дата_подписания)
- ClientBailContract: Договоры личного поручительства (имя_поручителя, паспорт, дата_договора)
- ClientDocuments: Загрузка файлов (файл, дата_загрузки, пользователь, клиент)
Модели рабочего процесса превышения лимита:
- OverLimitRequestModel: Запросы на продажу сверх лимита (клиент, менеджер, номер_счета, сумма_счета, сумма_превышения_лимита, обоснование, статус)
- OverLimitResponsibility: Аудит утверждения (запрос, утверждающий, решение, отметка_времени)
Модели просроченной задолженности:
- LateDebtDesc: Отдельные просроченные счета (клиент, номер_документа, сумма, дни_просрочки, договорная_ставка)
- ClientLateDebtComments: Комментарии по деятельности по сбору задолженности
Модели кредитного комитета:
- ClientCCResolution: Решения комитета (клиент, дата_заседания, решение, условия, положения, проголосовавшие_члены)
Организационные модели:
- Department: филиалы (название, код, активный_статус)
- Employees: Иерархия пользователей (пользователь, отдел, должность, менеджер, является_директором)
Модели приложения SWIFT (swift/models.py)
DevicesDB
├── id (PK)
├── user_id (CharField, ссылается на пользователя Django)
├── company (CharField, идентификатор компании: "inoxtrade.ru", "ariel.ru")
├── device_token (TextField, токен регистрации FCM)
├── device_type (CharField, "iOS"/"Android")
└── created_date (DateTimeField)
SwiftNotificationSettings
├── id (PK)
├── device (ForeignKey → DevicesDB)
├── status_filters (JSONField, массив идентификаторов статусов для уведомления)
├── comment_notifications (BooleanField)
└── updated_date (DateTimeField)
Модели приложения Users (users/models.py)
CompanyUsers
├── id (PK)
├── user (ForeignKey → User)
├── company (CharField, идентификатор арендатора)
└── role (CharField, роль пользователя в компании)
TariffModel
├── id (PK)
├── name (CharField, например, "500 юридических лиц")
├── legal_entities_count (IntegerField, 250/500/1000/1500/2000/3000)
├── monthly_price (DecimalField)
├── annual_price (DecimalField)
└── features (JSONField, возможности плана)
PaymentHistory
├── id (PK)
├── user (ForeignKey → User)
├── tariff (ForeignKey → TariffModel)
├── amount (DecimalField)
├── payment_date (DateTimeField)
├── yookassa_payment_id (CharField, внешний идентификатор транзакции)
└── status (CharField, "pending"/"completed"/"failed")
Demo
├── id (PK)
├── company_name (CharField)
├── contact_person (CharField)
├── email (EmailField)
├── phone (CharField)
├── message (TextField)
└── created_date (DateTimeField)
4. Архитектура API
RESTful Mobile API (swift/views.py)
Все конечные точки возвращают JSON, требуют аутентификации через сессию или токен.
Конечные точки веб-приложения (clients/urls.py)
Панель управления и представления списков:
GET / - Основная панель управления (KPI, последние действия)
GET /table/ - Фильтруемый список клиентов (Django Tables2)
GET /table-open/, /table-closed/, /table-new/, /table-late/ - Отфильтрованные представления
GET /late-debt-view/ - Анализ просроченной задолженности по отделам
GET /risk-view/ - Панель управления мониторингом рисков
Операции CRUD:
GET /create-client-sales/ - Форма новой заявки
POST /create-client-sales/ - Отправка новой заявки
GET /credit-risk-application/<pk>/ - Подробное представление заявки (основной UI)
POST /update-office-m/<pk>/ - Обновление назначения отдела/менеджера
GET /upload-contract-data/<pk>/ - Форма ввода данных договора
POST /upload-contract-data/<pk>/ - Сохранение условий договора
Действия рабочего процесса (асинхронные представления с уведомлениями):
POST /send-nop/<pk>/ - Отправка в отдел рисков
POST /send-kd/<pk>/ - Отправка директору по кредитам филиала
POST /client-kk-submission/<pk>/ - Отправка в кредитный комитет
POST /send-ceo/<pk>/ - Эскалация генеральному директору
POST /client-approval/<pk>/ - Утверждение заявки
POST /client-refusal/<pk>/ - Отклонение заявки
POST /open-limit/<pk>/ - Активация утвержденного кредитного лимита
POST /close-limit/<pk>/ - Отзыв/приостановка кредитного лимита
Интеграция данных:
POST /get-client-kontur-data/<pk>/ - Получение внешних данных о компании
- Вызывает Kontur API, заполняет ClientKonturData, ClientFinances, ClientTrials и т. д.
POST /upload-file-form-view/<pk>/ - Загрузка документа
POST /income-st/<pk>/ - Ручной ввод отчета о прибылях и убытках
POST /balance-st/<pk>/ - Ручной ввод баланса
Рабочий процесс превышения лимита:
POST /over-limit-request/<pk>/ - Создание запроса на превышение лимита
GET /over-limit-approval/<req>/ - Просмотр запроса на превышение лимита
POST /over-limit-vote-yes/<pk>/ - Утверждение превышения лимита
POST /over-limit-vote-no/<pk>/ - Отклонение превышения лимита
Управление уведомлениями:
GET /show-notifications/ - Пользовательский интерфейс центра уведомлений
GET /notifications/ - Конечная точка JSON (количество непрочитанных)
POST /clear-notifications/ - Отметить все как прочитанные
POST /delete-notifications/ - Удалить уведомление
Отчетность:
GET /export-clients/ - Экспорт списка клиентов в Excel
GET /cc-agenda/ - Генерация повестки дня кредитного комитета (PDF/электронная почта)
GET /cc-protocol/ - Генерация протокола заседания
5. Архитектура безопасности
Аутентификация и авторизация
- Аутентификация Django: Аутентификация на основе сессий для веба, на основе токенов для мобильных устройств
- Декораторы разрешений:
@login_required, пользовательский @group_required(['ХХХ', 'УУУ'])
- Управление доступом на основе ролей (RBAC): 8 групп пользователей с различными разрешениями:
manager: Создавать заявки, просматривать своих клиентов
assistants: Поддерживать менеджера в том же отделе
NOP: Оценка рисков, получение внешних данных
legal: Проверка договоров, проверка условий
accounting: Финансовый анализ
kom_dir: Утверждение лимитов на уровне филиала
KK: Члены кредитного комитета
secretary: Администратор, полный доступ к рабочему процессу
Защита данных
- Защита CSRF: Все формы требуют токен CSRF
- Предотвращение SQL-инъекций: Параметризованные запросы Django ORM
- Предотвращение XSS: Автоматическое экранирование шаблонов Django
- Валидация загружаемых файлов: Белый список разрешенных расширений, ограничения размера
- Хеширование паролей: да
Инфраструктурная безопасность
- Завершение SSL Nginx: Принудительный HTTPS
- Защита паролем Redis: Требуется AUTH
- Изоляция сети Docker: Сервисы взаимодействуют во внутренней сети
- Базовая аутентификация: Защищенные административные интерфейсы (/admin/, /prometheus/)
- Управление секретами: Переменные среды для ключей API, паролей
Безопасность API
- Требуется аутентификация: всех конечных точек мобильного API
- Конфигурация CORS: Ограниченные источники для доступа к API
- Проверка ввода: Django Forms и DRF Serializers проверяют все вводы
6. Ключевые паттерны проектирования
Разделение ответственности
- Модели: Чистые модели данных, минимальная бизнес-логика
- Представления: Обработка запросов, проверка разрешений, оркестрация
- Помощники: Интеграция с внешними API (Kontur, YooKassa, FCM)
- Сериализаторы: Преобразование данных для ответов API
- Формы: Валидация и отрисовка пользовательского ввода
- Таблицы/Фильтры: Логика отображения и запросов
Асинхронный/Уведомляющий паттерн
Каждое действие рабочего процесса следует этому паттерну:
def workflow_action(request, pk):
client = ClientsModel.objects.get(pk=pk)
if not user_has_permission(request.user, client):
return HttpResponseForbidden()
if client.status != expected_status:
return error_response()
old_status = client.status
client.status = new_status
client.save()
StatusHistory.objects.create(
client=client,
old_status=old_status,
new_status=new_status,
user=request.user
)
notify_users(client, new_status)
send_push_notification(client, new_status)
return JsonResponse({'success': True})
Архитектура с несколькими компаниями
- Идентификация арендатора: поле company ("inoxtrade.ru", "ariel.ru")
- Изоляция данных: Запросы фильтруются по компании в моделях с несколькими компаниями
- Общий код: Единая кодовая база обслуживает несколько компаний
- Настройки для конкретного арендатора: Учетные данные Firebase, платежные аккаунты для каждой компании
Оптимизация запросов с предварительной выборкой
clients = ClientsModel.objects.select_related(
'status', 'department', 'manager', 'director'
).prefetch_related(
'clientcreditcomments_set',
'statushistory_set',
'clientfinances',
'clientkonturdata'
)
Уменьшает проблему N+1 запросов в представлениях списков.
Автоматизация на основе сигналов
@receiver(post_save, sender=Demo)
def notify_sales_team(sender, instance, created, **kwargs):
if created:
send_email_to_sales(instance)
Запросы запускают автоматические уведомления по электронной почте.
Шаблон WebSocket Django Channels
class NotificationConsumer(WebsocketConsumer):
def connect(self):
self.user_id = self.scope['url_route']['kwargs']['user_id']
async_to_sync(self.channel_layer.group_add)(
f'user_{self.user_id}',
self.channel_name
)
def notification(self, event):
self.send(text_data=json.dumps(event['message']))
Доставка уведомлений в реальном времени подключенным клиентам.
7. Детали внешней интеграции
Интеграция с Kontur API (clients/helpers.py)
Ключевые функции:
def get_kontur_basics(inn, pk):
"""Получение регистрационных данных компании, информации о руководстве"""
endpoint = f'{BASE_URL}/req?inn={inn}&key={KONTUR_API_KEY}'
def get_kontur_trials(inn, pk):
"""Получение судебных дел, налоговых задолженностей, исполнительных производств"""
endpoint = f'{BASE_URL}/casesCount?inn={inn}&key={KONTUR_API_KEY}'
def get_kontur_financials(inn, pk):
"""Получение финансовой отчетности за 3+ года"""
endpoint = f'{BASE_URL}/buh?inn={inn}&key={KONTUR_API_KEY}'
def get_shareholders(inn, pk):
"""Получение структуры собственности"""
Обработка данных:
- Разбор ответа JSON с обработкой ошибок
- Итерация по финансовым данным за несколько лет
- Расчет коэффициентов (процент рентабельности, отношение долга к собственному капиталу)
- Сопоставление полей в зависимости от типа компании (ООО против АО)
Firebase Cloud Messaging (swift/views.py)
Инициализация:
import firebase_admin
from firebase_admin import messaging
firebase_admin.initialize_app(credentials.Certificate('firebase-key.json'))
Функция push-уведомлений:
def send_fcm_notification(user_id, title, body, data):
devices = DevicesDB.objects.filter(user_id=user_id)
for device in devices:
message = messaging.Message(
notification=messaging.Notification(title=title, body=body),
data=data,
token=device.device_token
)
messaging.send(message)
Триггеры уведомлений:
- Изменение статуса: "Заявка [client_name] переведена в кредитный комитет"
- Новый комментарий: "Менеджер прокомментировал заявку по клиенту [client_name]"
- Запрос на превышение лимита: "Запрос на превышение лимита требует вашего одобрения"
- Оповещение о просроченной задолженности: "Клиент [client_name] просрочил платеж на 30 дней"
Платежный шлюз YooKassa (users/helpers.py)
Конфигурация:
from yookassa import Configuration, Payment
Configuration.account_id = 'your_shop_id'
Configuration.secret_key = 'your_secret_key'
Поток платежей:
def payment_helper(user, tariff, billing_cycle):
amount = tariff.monthly_price if billing_cycle == 'monthly' else tariff.annual_price
payment = Payment.create({
"amount": {"value": str(amount), "currency": "RUB"},
"confirmation": {
"type": "redirect",
"return_url": "https://yoursite.com/payment-return/"
},
"capture": True,
"description": f"Subscription: {tariff.name}"
})
PaymentHistory.objects.create(
user=user,
tariff=tariff,
amount=amount,
yookassa_payment_id=payment.id,
status='pending'
)
return payment.confirmation.confirmation_url
def check_payment(payment_id):
payment = Payment.find_one(payment_id)
if payment.status == 'succeeded':
PaymentHistory.objects.filter(yookassa_payment_id=payment_id).update(status='completed')
8. Оптимизация производительности
- Индексирование базы данных: Индексы по client_inn, status, department, created_date
- Оптимизация запросов: select_related() и prefetch_related() в представлениях списков
- Кэширование Redis: Хранение сессий, фреймворк кэша Django
- CDN для статических файлов: Nginx напрямую обслуживает статические файлы (в обход Django)
- Пагинация: Пагинация Django Tables2 для больших наборов данных
- Асинхронные задачи: Celery
- Горизонтальное масштабирование: Распределение нагрузки между компаниями экземплярами Docker
9. Тестирование и обеспечение качества
Инфраструктура тестирования:
- pytest - Фреймворк для тестирования
- pytest-django - Плагин pytest для Django
- Присутствуют инструменты для покрытия кода
Инструменты качества:
- Django Debug Toolbar
- Django Extensions (shell_plus, runserver_plus)
- Логирование SQL в процессе разработки
Вопросы масштабируемости
Текущие ограничения:
- Синхронная обработка платежей (могла бы выиграть от очереди задач)
- Внутрипроцессные соединения WebSocket (не масштабируется горизонтально без "липких" сессий)
Улучшения масштабируемости (на будущее):
- Внедрение Celery: Перенос вызовов Kontur API, отправки уведомлений в фоновые рабочие процессы
- Добавление Redis Cluster: Распределенное кэширование и хранение сессий
- Отдельный CDN для статических файлов: Перенос доставки статических ресурсов
- Реплики для чтения базы данных: Раздельные соединения для чтения/записи базы данных
- Elasticsearch: Полнотекстовый поиск по именам клиентов, комментариям
- Объектное хранилище: Перемещение загружаемых файлов в хранилище, совместимое с S3
Уникальные технические особенности
- Гибридная синхронно-асинхронная архитектура: Django (синхронный) + Channels (асинхронные WebSockets)
- Глубокая интеграция внешних данных: Автоматическая оценка кредитных рисков через Kontur API
- Многопользовательский SaaS: Единая кодовая база обслуживает несколько компаний
- API, ориентированный на мобильные устройства: Комплексный RESTful API, разработанный для мобильного потребления
- Уведомления в реальном времени: Уведомления WebSocket для мгновенной командной связи
- Полный аудит: Полная история всех действий, решений, изменений статуса
- Гибкая маршрутизация уведомлений: Настраиваемые пользователем предпочтения уведомлений для каждого устройства
- Интеграция платежей: Российский платежный шлюз (YooKassa) для оплаты подписок