# README
Сервис динамического сегментирования пользователей
Запуск
git clone https://github.com/realPointer/segments
cd segments
make compose-up
Для запуска сервиса с интеграцией с Yandex Disk нужно:
- Получить OAuth-токен Тык!
- Вписать его в переменную окружения YANDEX_TOKEN в
.env
Swagger
После запуска приложения доступна Swagger-документация по адресу http://localhost:8080/swagger/index.html
Запросы
Создание пользователя
curl --location --request POST 'localhost:8080/v1/user/{user_id}'
Получение сегментов пользователя
curl --location 'localhost:8080/v1/user/{user_id}/segments'
Пример ответа:
[
"Segment1",
"Segment2",
"Segment3"
]
Создание сегмента
?auto={percentage}
- опциональный параметр. Лучше туда передать число >0 и <=100
Без него сегмент просто добавится. Дальше можно будет привязать его к какому-нибудь пользователю самостоятельно
curl --location --request POST 'localhost:8080/v1/segment/{segment_name}?auto={percentage}'
Удаление сегмента
При удалении сегмента он будет отвязан у всех пользователей. Это запишется в историю каждого пользователя
curl --location --request DELETE 'localhost:8080/v1/segment/{segment_name}'
Получение списка сегментов
curl --location 'localhost:8080/v1/segment/list'
Пример ответа:
[
"Segment1",
"Segment2",
"Segment3"
]
Добавление и удаление сегментов пользователю
"expire": "1m"
- опциональный параметр. Через это время сегмент будет удалён
А вот такие единицы измерения он может принять: "ns", "µs", "ms", "s", "m", "h"
Также можно лишь добавить или же удалить сегменты
curl --location 'localhost:8080/v1/user/{user_id}/segments' \
--header 'Content-Type: application/json' \
--data '{
"add_segments": [
{
"name": "{segment_name}"
},
{
"name": "{segment_name}",
"expire": "1m"
}
],
"delete_segments": [
"{segment_name}"
]
}'
Получение операций пользователя в CSV
?date={year}-{month}
- опциональный параметр. Без него будет выведена полная история пользователя
curl --location 'localhost:8080/v1/user/{user_id}/operations?date={year}-{month}'
Пример ответа:
(1, AVITO, add, 2023-08-31 14:24:33.253191 +0000 UTC)
(1, AVITO_300, add, 2023-08-31 14:24:33.253191 +0000 UTC)
(1, AVITO, delete, 2023-08-31 14:24:33.253191 +0000 UTC)
(1, AVITO_300, delete, 2023-08-31 14:24:54.664546 +0000 UTC)
(1, AVITO, add, 2023-08-31 14:26:18.835481 +0000 UTC)
(1, AVITO, delete, 2023-08-31 14:26:36.639305 +0000 UTC)
(1, TEST_AUTO, add, 2023-08-31 15:51:20.77629 +0000 UTC)
Получение ссылки на скачивание операций пользователя в CSV
?date={year}-{month}
- опциональный параметр. Без него в файле будет полная история
curl --location 'localhost:8080/v1/user/{user_id}/operations/report-link?date={year}-{month}'
Пример ответа:
Вот это ссылочка! 😱😱😱 Пожалуй, скрою её под текстом :d
Очень длинная ссылка, которую выдаёт API Яндекс Диска
Задания
Основное задание (минимум):
- Метод создания сегмента
- Метод удаления сегмента
- Метод добавления и удаления пользователя в сегмент
- Метод получения активных сегментов пользователя
Доп. задание 1:
- Сохранение истории попадания/выбывания пользователя из сегмента с возможностью получения отчета по пользователю за определенный период
Создана отдельная таблица user_segments_log, в которую записываются действия с каждым сегментом пользователя. Имеется возможность получить отчёт за определённый месяц.
Так как в задании говорится о получении ссылки, то реализован метод получения отчёта с Яндекс Диска. Для этого были использованы стандартные методы API Диска
Доп. задание 2:
- Реализовать возможность задавать TTL (время автоматического удаления пользователя из сегмента)
Данное задание было сделано через пакет планирования go-cron. Каждую минуту происходит выполнение функции, которая ищет устаревшие записи, удаляет и заносит их в историю.
В целом, эту задачу можно было бы реализовать, например, через простую горутину, триггер в базе данных или же cron как отдельная утилита или pgcron - расширение в базе данных.
Доп. задание 3:
- Добавить опцию указания процента пользователей, которые будут попадать в сегмент автоматически
Добавлен опциональный параметр ?auto={percentage}
. Если его передать, то сегмент автоматически будет привязан к указанному проценту пользователей
Какие-то дополнительные мысли
- Так как в деталях по заданию было указано, что механизм миграции не нужен, то база создаётся при первичной инициализации репозитория. Итоговые таблицы лежат в schemes/scheme.sql
- Была изначально идея генерировать UID для каждого пользователя. Но так как скорее всего в сервисе база пользователей должна поступать извне, то были сделаны обычные целочисленный id
- Достаточно поздно подумал, что в целом все входные параметры можно передавать JSONом, но в пути даже проще
- Использование транзакций для добавления или удаление сегментов у пользователя, чтобы и история точно записалась
- Так как уровень репозитория написан через интерфейсы, то не будет никаких проблем сгенерировать для них моки
- Стоило бы пользоваться гитом не только для финального коммита. Может вообще в следующий раз попробовать GitFlow 🤔
TODO
- Немного валидации. Хоть и присутствует некоторая по типу введённой даты или числового id
- CI/CD