Skip to content

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lead Routing Service (mini CRM)

📌 Описание

Lead Routing Service — это микросервис на FastAPI, отвечающий за:

  • управление операторами и их нагрузкой;
  • хранение лидов и их обращений;
  • маршрутизацию новых обращений по операторам с учётом лимитов и весов;
  • настройку распределения трафика по источникам (ботам).

Проект использует Python, FastAPI, SQLAlchemy, SQLite.

Запуск осуществляется через файл main.py, содержащий конструкцию:

if __name__ == "__main__":
    ...

📂 Структура проекта

project/                - корневая директория проекта
├── main.py             - точка запуска приложения
├── settings.py         - модуль для работы с переменными окружениям
├── .env                - файл с секретами (добавлен в VCS специально в демонстрационных целях)
└── .database.db        - файл БД (добавлен в VCS специально в демонстрационных целях)
└── requirements.txt    - файл с зависимостями
└── app/                - пакет с составляющими сервиса
    ├── __init__.py     - модуль инициализации (предусмотрен для возможного горизонтальеного масштибирования)
    ├── models.py       - модуль с Pydantic моделями
    ├── schemas.py      - модуль со схемой БД
    ├── services.py     - модуль с основной бизнес-логикой сервиса
    ├── repository.py   - модуль для взаимодействия с БД
    ├── controllers.py  - модуль с FastAPI эндпоинтами
    ├── routers.py      - модуль с маршрутизатором сервиса (предусмотрен для возможного горизонтальеного масштибирования)

⚙️ Технологии

  • Python 3.12+
  • FastAPI
  • SQLAlchemy (async + sync)
  • SQLite
  • Pydantic / pydantic-settings

▶️ Запуск проекта

1. Установить зависимости

pip install -r requirements.txt

2. Настроить переменные окружения (.env)

Пример:

DATABASE_URL=sqlite+aiosqlite:///./database.db

3. Запуск через main.py

python main.py

FastAPI поднимет сервер на:

http://127.0.0.1:8000

4. Документация

Автоматически создаётся по адресу:

http://127.0.0.1:8000/docs

🗄️ Модели данных

Operator (операторы)

  • name - имя
  • is_active - активность
  • max_concurrent - лимит нагрузки
  • source_weights - relationship атрибут (связь с OperatorSourceWeight)
  • contacts - relationship атрибут (связь с Contact)

Source (боты / источники)

  • code - уникальный идентификатор источника, например bot_telegram
  • name - имя
  • description - описание источника
  • source_weights - relationship атрибут (связь с OperatorSourceWeight)
  • contacts - relationship атрибут (связь с Contact)

OperatorSourceWeight (ассоциативная таблица для связи Many-to-Many между Operator и Source)

  • operator_id - идентификатор оператора (Foreign Key для Operator.id)
  • source_id - идентификатор источника (Foreign Key для Source.id)
  • weight - вес / сила связи оператора с источником

Lead (лиды, клиенты)

  • external_id - идентификатор источника, из которого пришел лид. По сути Lead.external_id = Source.code. Необходим для осуществления бизнес логики
  • phone - номер телефона
  • email - электронная почта
  • created_at - дата создания
  • contacts - relationship атрибут (связь с Contact)

Contact (обращения)

  • lead_id - идентификатор лида (Foreign Key для Lead.id)
  • source_id - идентификатор источника (Foreign Key для Source.id)
  • operator_id - назначенный оператор или None ((Foreign Key для Operator.id))
  • status - статус обращения (Enum-перечисление из new, assigned, in_progress, closed)
  • payload - содержимое обращения
  • created_at - дата создания
  • lead - relationship атрибут (связь с Lead)
  • source - relationship атрибут (связь с Source)
  • operator - relationship атрибут (связь с Operator)

🗄️ Схематичная схема) БД

Alt text

🔀 Алгоритм распределения обращения

1. Как определяется, что обращения принадлежат одному и тому же лиду

При поступлении нового обращения система выполняет поиск лида по одному или нескольким уникальным признакам:

  • телефон;
  • email;
  • внешний идентификатор (например, ID пользователя в боте);

Если лид найден — новое обращение связывается с ним. Если нет — создаётся новый лид.


2. Как учитываются веса операторов по источникам

У каждого источника (бота) задан список операторов с их весами:

оператор A — вес 10
оператор B — вес 30
оператор C — вес 60

Для распределения используется формула вероятности:

выбор оператора = вес оператора / сумма всех весов

Пример: Сумма = 10 + 30 + 60 = 100.

  • A получает ~10% обращений,
  • B — ~30%,
  • C — ~60%.

Мы используем взвешенный случайный выбор.


3. Как учитываются лимиты нагрузки операторов

У каждого оператора есть поле max_concurrent — максимально допустимое количество активных обращений.

Перед распределением система фильтрует операторов:

  • оператор должен быть активен (is_active=True),
  • его текущая нагрузка < max_concurrent.

Если оператор выбран весовым алгоритмом, но его лимит превышен, система:

  1. исключает его из списка,
  2. повторяет выбор среди оставшихся,
  3. если доступных не остаётся — назначение не происходит.

4. Что происходит, если подходящих операторов нет

Если:

  • все операторы неактивны,
  • или превышены лимиты нагрузки,
  • или для источника нет настроенных операторов,

то создаётся обращение без оператора (operator_id = None).

Этот вариант был выбран как наиболее гибкий и безопасный. Ошибка 4xx не возвращается — данные не теряются, обращение фиксируется.


📡 API (краткое описание)

Операторы

POST /operators
GET  /operators
PATCH /operators/{operator_id}

Источники

POST /sources
POST /sources/{source_id}

Регистрация обращения

POST /contacts/{source_code}

Просмотр обращений

GET /contacts_and_leads
GET /contacts_by_operators
GET /contacts_by_sources

📝 Примечания

  • Автоматическое создание таблиц происходит при запуске сервиса.
  • Лимит нагрузки считается количеством активных обращений оператора.
  • Если нет доступного оператора, обращение создаётся без назначения.

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages