Customer Service
Ответственность
CRM-сервис: управление клиентами (end-users сети, не сотрудниками), их адресами доставки, группами клиентов (статические и динамические с правилами автозаполнения) и привязкой к заказам.
Вынесен из User Service в отдельный микросервис (BR 3.1, см. Roadmap — Скидки и лояльность) так как:
- Customer — внешний user со своим жизненным циклом (регистрируется кассиром / через сайт / через мобильное приложение), отдельным от сотрудников
- Write-heavy нагрузка: каждый заказ потенциально создаёт запись / обновляет
customer.last_visit - Customer BFF (
:3021— сайт и мобильное приложение клиентов) независимо от Admin BFF потребляет этот сервис - Будущий Loyalty Service (
:3007) активно читает и пишет связанные сущности (баллы, транзакции) — отдельный микросервис с чистыми event-контрактами упрощает интеграцию
Ключевые функции
Клиенты (BR 3.1)
- CRUD клиентов с soft delete + анонимизацией PII по ФЗ-152
- Поиск по нормализованному телефону (E.164) — основной ключ
- Фильтры по источнику регистрации, группе, диапазону даты регистрации
- Быстрое создание клиента на POS — минимальная форма (phone + имя) + автоматическое прикрепление к заказу
- Merge дубликатов (API-only в MVP) — объединение двух клиентов в одного с переносом адресов и истории
- Ролевой доступ:
- Владелец франшизы / партнёра с
customers.read/customers.edit— полный CRUD в админке - Кассир с
customers.create_quick— поиск по phone + quick-create + прикрепление к заказу на POS (без доступа к списку в админке)
- Владелец франшизы / партнёра с
Адреса клиентов (BR 3.1)
- CRUD адресов (один клиент — N адресов: дом / работа / …)
- Ровно один default на клиента (переключение в одной транзакции)
- Ссылка на
delivery_zonesStore Service — логическая, без синхронной валидации в MVP
Группы клиентов (BR 3.1)
- CRUD групп двух типов:
- Статические — админ добавляет/удаляет клиентов вручную
- Динамические — членство рассчитывается по правилам (JSONB
rules_json)
- Каталог правил автозаполнения (MVP): total_spent_all_time, total_spent_period, days_inactive, birthday_window, city, delivery_zone, gender, registration_source, include_groups, exclude_groups. До 5 правил на группу, логика AND.
- Пересчёт динамических групп:
- Scheduler раз в сутки (03:00 МСК) — полный пересчёт всех dynamic групп всех франшиз. Fallback на случай пропущенных событий
- Триггерно через Kafka consumer
order.completedиcustomer.updated— точечный пересчёт для одного клиента - Ручной через
POST /customer-groups/{id}/recompute
- Ролевой доступ: CRUD групп — только Владелец франшизы (
customer_groups.edit)
Kafka producer/consumer
- Публикует:
customer.created,customer.updated,customer.deleted,customer-group.member-changed(для будущих Loyalty / Notification Service) - Потребляет:
order.completed(Order Service) — для точечного пересчёта dynamic групп
Авторизация
JWT валидируется локально (HS256 + shared
JWT_SECRET). Паттерн как в User Service / Store Service / Warehouse Service.
- Public API — Bearer JWT сотрудника (scope франшизы вычисляется в Auth Service / User Service; Customer Service использует
franchise_idиз JWT + проверку permissions) - Internal API —
X-Service-Token(один на все internal-вызовы между нашими сервисами, не меняется per-user)
Клиентская авторизация (регистрация end-user’а через мобильное приложение / сайт через OTP по SMS) — out of scope BR 3.1. Появится в BR 3.5 (Customer auth). Пока Customer Service только хранит клиента; сам клиент в систему не логинится.
Зависимости
- PostgreSQL (
customer_db) — основное хранилище (отдельная БД, не разделяется с user_db) - Kafka — producer (
customer.*events) + consumer (order.completed) - Внешние сервисы — НЕТ синхронных вызовов в MVP:
- Валидация
delivery_zone_idв правилах dynamic групп — без cross-service check. Если zone удалена в Store Service, правило перестанет попадать ни в одного клиента (не критично; можно добавить internal check в отдельной BR) - Валидация
registered_by_employee_id— без cross-service check (логическая ссылка, при удалении сотрудника значение остаётся, исторически корректно) - Валидация
customer_idприorder.completed— если customer не существует, событие логируется и игнорируется
- Валидация
Конфигурация
| Variable | Description | Default |
|---|---|---|
DATABASE_URL | PostgreSQL connection string | — |
SERVICE_TOKEN | Токен для internal API | — |
JWT_SECRET | Ключ для локальной валидации JWT (HS256) | — |
KAFKA_BOOTSTRAP_SERVERS | Kafka brokers | — |
CUSTOMER_GROUPS_RECOMPUTE_CRON | Расписание полного пересчёта dynamic групп | 0 0 3 * * * |
PORT | HTTP порт | 3013 |