diff --git a/internal-documentation/documentation-from-space/development/debug-mode.md b/internal-documentation/documentation-from-space/development/debug-mode.md new file mode 100644 index 00000000..881e1f65 --- /dev/null +++ b/internal-documentation/documentation-from-space/development/debug-mode.md @@ -0,0 +1,2 @@ +cookie - r46_search=1 +параметр - debug=true diff --git a/internal-documentation/documentation-from-space/development/gmail-ascess.md b/internal-documentation/documentation-from-space/development/gmail-ascess.md new file mode 100644 index 00000000..e89d60ae --- /dev/null +++ b/internal-documentation/documentation-from-space/development/gmail-ascess.md @@ -0,0 +1,7 @@ +вход в Gmail акк для шопифай + +логин: team@marstack.app + +пароль: AeYu5CL14QMQAM2dF67 + +резервный доступ через телефонный номер (Миши) и почту mk@rees46.com diff --git a/internal-documentation/documentation-from-space/development/images/DNS-settings.png b/internal-documentation/documentation-from-space/development/images/DNS-settings.png new file mode 100644 index 00000000..7f60bb8b Binary files /dev/null and b/internal-documentation/documentation-from-space/development/images/DNS-settings.png differ diff --git a/internal-documentation/documentation-from-space/development/images/android-close.png b/internal-documentation/documentation-from-space/development/images/android-close.png new file mode 100644 index 00000000..95f7ff06 Binary files /dev/null and b/internal-documentation/documentation-from-space/development/images/android-close.png differ diff --git a/internal-documentation/documentation-from-space/development/images/android-release.png b/internal-documentation/documentation-from-space/development/images/android-release.png new file mode 100644 index 00000000..8480ba3e Binary files /dev/null and b/internal-documentation/documentation-from-space/development/images/android-release.png differ diff --git a/internal-documentation/documentation-from-space/development/images/android-staging-repositories.png b/internal-documentation/documentation-from-space/development/images/android-staging-repositories.png new file mode 100644 index 00000000..6044c165 Binary files /dev/null and b/internal-documentation/documentation-from-space/development/images/android-staging-repositories.png differ diff --git a/internal-documentation/documentation-from-space/development/images/android-successful-download.png b/internal-documentation/documentation-from-space/development/images/android-successful-download.png new file mode 100644 index 00000000..2f8880c3 Binary files /dev/null and b/internal-documentation/documentation-from-space/development/images/android-successful-download.png differ diff --git a/internal-documentation/documentation-from-space/development/images/autovaz-integration-streams-list.png b/internal-documentation/documentation-from-space/development/images/autovaz-integration-streams-list.png new file mode 100644 index 00000000..21ecc698 Binary files /dev/null and b/internal-documentation/documentation-from-space/development/images/autovaz-integration-streams-list.png differ diff --git a/internal-documentation/documentation-from-space/development/marstack-4-0.md b/internal-documentation/documentation-from-space/development/marstack-4-0.md new file mode 100644 index 00000000..5bee3e68 --- /dev/null +++ b/internal-documentation/documentation-from-space/development/marstack-4-0.md @@ -0,0 +1,17 @@ +team@marstack.app +8MpCaj9Wew9FIB + +(!!!Не заходить с российского IP!!!) + + + + + +Магазин "My Store" перенесен на акк + +shop@marstack.app +54MpCaj9Wew9FIB + +Нужно деактивировать до 17-го марта, дальше подписка 39$ + +(!!!Не заходить с российского IP!!!) diff --git "a/internal-documentation/documentation-from-space/development/\320\220\320\262\321\202\320\276\320\222\320\220\320\227. Kafka.md" "b/internal-documentation/documentation-from-space/development/\320\220\320\262\321\202\320\276\320\222\320\220\320\227. Kafka.md" new file mode 100644 index 00000000..a0ade34f --- /dev/null +++ "b/internal-documentation/documentation-from-space/development/\320\220\320\262\321\202\320\276\320\222\320\220\320\227. Kafka.md" @@ -0,0 +1,34 @@ +Установите сертификат: + +``` +mkdir -p /usr/local/share/ca-certificates/Yandex && \ +wget "https://storage.yandexcloud.net/cloud-certs/CA.pem" -O /usr/local/share/ca-certificates/Yandex/YandexCA.crt +``` +Пример команды для отправки сообщения в топик с SSL: + +``` +echo "test message" | kafkacat -P \ + -b rc1c-e5bcr1ief01crf2q.mdb.yandexcloud.net:9091 \ + -t \ + -X security.protocol=SASL_SSL \ + -X sasl.mechanisms=SCRAM-SHA-512 \ + -X sasl.username= \ + -X sasl.password= \ + -X ssl.ca.location=/usr/local/share/ca-certificates/Yandex/YandexCA.crt - +Z -K: +``` +Пример команды для получения сообщений из топика: + +``` +kafkacat -C \ + -b rc1c-e5bcr1ief01crf2q.mdb.yandexcloud.net:9091 \ + -t \ + -X security.protocol=SASL_SSL \ + -X sasl.mechanisms=SCRAM-SHA-512 \ + -X sasl.username= \ + -X sasl.password= \ + -X ssl.ca.location=/usr/local/share/ca-certificates/Yandex/YandexCA.crt - +Z -K: +``` + +![img.png](./images/autovaz-integration-streams-list.png) diff --git "a/internal-documentation/documentation-from-space/development/\320\232\320\260\320\272 \321\200\320\260\320\261\320\276\321\202\320\260\321\216\321\202 \321\204\320\273\320\260\320\263\320\270 \320\277\320\276\320\264\320\277\320\270\321\201\320\276\320\272.md" "b/internal-documentation/documentation-from-space/development/\320\232\320\260\320\272 \321\200\320\260\320\261\320\276\321\202\320\260\321\216\321\202 \321\204\320\273\320\260\320\263\320\270 \320\277\320\276\320\264\320\277\320\270\321\201\320\276\320\272.md" new file mode 100644 index 00000000..3f8e5460 --- /dev/null +++ "b/internal-documentation/documentation-from-space/development/\320\232\320\260\320\272 \321\200\320\260\320\261\320\276\321\202\320\260\321\216\321\202 \321\204\320\273\320\260\320\263\320\270 \320\277\320\276\320\264\320\277\320\270\321\201\320\276\320\272.md" @@ -0,0 +1,86 @@ +# Работа с подписками и отписками + +Новые флаги подписок/отписок хранятся в таблице `client_unsubscribes`. Для каждого клиента существует виртуальная двухмерная матрица флагов, состоящая из `channel` (канал отправки) и `message_type` (тип сообщения). + +**Каналы отправки:** + +* Email +* Телефон +* Веб пуш +* Мобильный пуш +* Телеграм + +**Типы сообщений:** + +* Массовые рассылки (Bulk) +* Цепочки (Chain) +* Транзакционные (Transactional) + +Пример: клиент с указанными Email, Phone и Telegram. Его подписки можно представить в виде таблицы: + +| | Email | Phone | WebPush | MobilePush | Telegram | +| ------------- | ----- | ----- | ------- | ---------- | -------- | +| Bulk | ✅ | ❌ | | | ❌ | +| Chain | ❌ | ✅ | | | ✅ | +| Transactional | ✅ | ✅ | | | ✅ | + +В таблице БД будут следующие записи: + +```text +shop_id | channel_type | channel_id | message_type +--------|--------------|----------------|-------------- +1 | email | test@test.com | chain +1 | phone | 7912345678 | bulk +1 | telegram | 1234567890 | bulk +``` + +Хранятся только отписки — то есть записи в таблице обозначают отключённые каналы и типы сообщений. + +### Проверка подписки клиента на канал + +**Ruby:** + +```ruby +client.subscribed?(ClientUnsubscribe::CHANNEL_EMAIL, ClientUnsubscribe::TYPE_CHAIN) +``` + +**SQL:** + +```sql +SELECT 1 FROM client_unsubscribes +WHERE shop_id = 1 + AND channel_type = 'email' + AND channel_id = 'test@test.com' + AND message_type = 'chain' +LIMIT 1 +``` + +### Получить список клиентов, подписанных на канал email в массовых рассылках + +**Ruby:** + +```ruby +shop.clients.joins("LEFT JOIN client_unsubscribes \ + ON client_unsubscribes.shop_id = clients.shop_id \ + AND client_unsubscribes.channel_type = '\#{ClientUnsubscribe::CHANNEL_EMAIL}' \ + AND client_unsubscribes.channel_id = clients.\#{ClientUnsubscribe::CHANNEL_ID[ClientUnsubscribe::CHANNEL_EMAIL]}") +.where(client_unsubscribes: {message_type: nil}) +``` + +**SQL:** + +```sql +SELECT clients.* FROM clients +LEFT JOIN client_unsubscribes + ON client_unsubscribes.shop_id = clients.shop_id + AND client_unsubscribes.channel_type = 'email' + AND client_unsubscribes.channel_id = clients.email +WHERE clients.shop_id = 1 + AND client_unsubscribes.message_type IS NULL +``` + +⚠️ **Важно:** не хардкодьте значения `channel_type` и `message_type`. Используйте соответствующие константы. + +⚠️ **Важно:** при поиске по `client_unsubscribes` обязательно фильтровать по `shop_id`, `channel_type`, `channel_id`. + +❗ **Изменения данных** в `client_unsubscribes` допускаются **только в API-проекте** и **только через статичные методы класса `ClientUnsubscribe`**. diff --git "a/internal-documentation/documentation-from-space/development/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265 \321\215\321\202\320\260\320\277\320\276\320\262 \321\200\321\203\321\207\320\275\320\276\320\271 \320\270\320\275\321\202\320\265\320\263\321\200\320\260\321\206\320\270\320\270 \320\275\320\260 \321\201\320\260\320\271\321\202\320\265.md" "b/internal-documentation/documentation-from-space/development/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265 \321\215\321\202\320\260\320\277\320\276\320\262 \321\200\321\203\321\207\320\275\320\276\320\271 \320\270\320\275\321\202\320\265\320\263\321\200\320\260\321\206\320\270\320\270 \320\275\320\260 \321\201\320\260\320\271\321\202\320\265.md" new file mode 100644 index 00000000..dfa9efb7 --- /dev/null +++ "b/internal-documentation/documentation-from-space/development/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265 \321\215\321\202\320\260\320\277\320\276\320\262 \321\200\321\203\321\207\320\275\320\276\320\271 \320\270\320\275\321\202\320\265\320\263\321\200\320\260\321\206\320\270\320\270 \320\275\320\260 \321\201\320\260\320\271\321\202\320\265.md" @@ -0,0 +1,144 @@ +# Товарный фид + +🔗 [https://rees46.ru/docs/ru/setup/products/](https://rees46.ru/docs/ru/setup/products/) + +--- + +# Трекинг событий + +## Обязательные события + +### Просмотр товара + +Передается на странице товара или на странице категории, если для просмотра используется модальное окно. +**Важно:** если просмотр товара происходит после перехода из инструмента (поиск, товарные рекомендации и т.д.) — в событии просмотра необходимо передать параметры инструмента: +`recommended_by`, `recommended_code` +🔗 [https://reference.api.rees46.com/#user-viewed-a-product](https://reference.api.rees46.com/#user-viewed-a-product) + +--- + +### Добавление, удаление, обновление корзины + +Передаётся с любой страницы, где товар можно добавить в корзину, а также со страницы самой корзины, где можно изменять её состав. +**Важно:** если добавление товара в корзину происходит после перехода из инструмента (поиск, товарные рекомендации и т.д.) — в событии просмотра необходимо передать параметры инструмента: +`recommended_by`, `recommended_code` +🔗 [https://reference.api.rees46.com/#user-added-product-to-cart](https://reference.api.rees46.com/#user-added-product-to-cart) + +--- + +### Оформление заказа + +🔗 [https://reference.api.rees46.com/#user-purchased-products](https://reference.api.rees46.com/#user-purchased-products) + +--- + +### Просмотр категории + +🔗 [https://reference.api.rees46.com/#user-viewed-a-category](https://reference.api.rees46.com/#user-viewed-a-category) + +--- + +### Поисковый запрос + +🔗 [https://reference.api.rees46.com/#user-searched-something](https://reference.api.rees46.com/#user-searched-something) + +--- + +**P.S. Параметры рекомендованного события** + +* `recommended_by`: + + * рекомендации — `dynamic` + * быстрый поиск — `instant_search` + * полный поиск — `full_search` +* `recommended_code`: + + * рекомендации — код блока + * быстрый или полный поиск — поисковый запрос + +--- + +## Необязательные события + +### Добавление, удаление, обновление избранного + +🔗 [https://reference.api.rees46.com/#user-added-product-to-favorites](https://reference.api.rees46.com/#user-added-product-to-favorites) +🔗 [https://reference.api.rees46.com/#user-removed-product-from-favorites](https://reference.api.rees46.com/#user-removed-product-from-favorites) + +--- + +### Кастомные события + +🔗 [https://reference.api.rees46.com/#track-custom-event](https://reference.api.rees46.com/#track-custom-event) + +--- + +## Проверка передачи событий + +**Личный кабинет магазина -> Настройки -> Статус подключения** + +--- + +# Профиль пользователя + +При каждом изменении данных пользователя (авторизация, регистрация, изменение данных) необходимо их передавать. +🔗 [https://reference.api.rees46.com/#user-39-s-profile](https://reference.api.rees46.com/#user-39-s-profile) + +--- + +# Интеграция инструментов + +## Товарные рекомендации + +При работе с товарными рекомендациями нужно учитывать, что алгоритмы блока ожидают данные со страницы, например ID просматриваемой категории или товара, поисковый запрос, локация, бренд. Ниже приведен общий рекомендованный алгоритм установки блоков на страницах сайта. + +* **Главная** — нет обязательных параметров +* **Категория** — необходимо передать ID текущей категории +* **Товар** — необходимо передать ID текущего товара +* **Корзина** — корзину передавать не нужно, она собирается из событий и хранится в профиле пользователя +* **Результаты поиска** — необходимо передать поисковый запрос +* **Другие страницы** (например: 404, блог, контакты) + +**JS SDK метод запроса товарных рекомендаций** +🔗 [https://reference.api.rees46.com/#request-product-recommendations](https://reference.api.rees46.com/#request-product-recommendations) + +--- + +## Поиск + +Поиск делится на быстрый и полный. + +* **Быстрый поиск** — показывает результаты при вводе поискового запроса + 🔗 [https://reference.api.rees46.com/#instant-search](https://reference.api.rees46.com/#instant-search) +* **Полный поиск** — используется на странице вывода результатов + 🔗 [https://reference.api.rees46.com/#full-search](https://reference.api.rees46.com/#full-search) + +--- + +# Настройка DNS + +Необходимо добавить почтовый домен в раздел **Настройки -> Почтовые домены** + +Рекомендуется создать для отправки разных типов писем отдельные поддомены. Это также позволит избежать конфликтов с существующими DNS записями на основном домене: + +* `b.comain.com` — массовые рассылки (bulk) +* `c.comain.com` — триггерные рассылки (chain) +* `t.comain.com` — транзакционные рассылки (transact) + +Для каждого домена на странице создания будет сгенерирована инструкция по добавлению DNS записей. + +![img.png](images/DNS-settings.png) +--- + +# Импорт истории заказов + +Для того, чтобы система быстрее обучилась, можно передать историю заказов пользователей за последние 6–24 месяца. +**Метод:** [https://reference.api.rees46.com/#import-orders](https://reference.api.rees46.com/#import-orders) +Отмененные заказы можно не передавать. + +--- + +# Импорт аудитории + +Для быстрого запуска массовых рассылок, можно передать данные о клиентах. +🔗 [https://reference.api.rees46.com/#import-users](https://reference.api.rees46.com/#import-users) diff --git "a/internal-documentation/documentation-from-space/development/\320\236\321\202\321\201\320\273\320\265\320\266\320\270\320\262\320\260\320\275\320\270\320\265 MTA \320\262 \320\261\320\260\320\275 \320\273\320\270\321\201\321\202\320\260\321\205.md" "b/internal-documentation/documentation-from-space/development/\320\236\321\202\321\201\320\273\320\265\320\266\320\270\320\262\320\260\320\275\320\270\320\265 MTA \320\262 \320\261\320\260\320\275 \320\273\320\270\321\201\321\202\320\260\321\205.md" new file mode 100644 index 00000000..f6323f13 --- /dev/null +++ "b/internal-documentation/documentation-from-space/development/\320\236\321\202\321\201\320\273\320\265\320\266\320\270\320\262\320\260\320\275\320\270\320\265 MTA \320\262 \320\261\320\260\320\275 \320\273\320\270\321\201\321\202\320\260\321\205.md" @@ -0,0 +1,85 @@ +
Актуальный список IP адресов + + +``` +78.46.208.108 +88.198.115.20 +88.198.150.80 +88.99.127.136 +116.202.10.131 +78.46.169.128 +78.46.183.37 +49.12.108.73 +49.12.106.192 +49.12.75.91 +49.12.79.84 +49.12.106.7 +88.198.202.24 +49.12.73.157 +49.12.104.230 +49.12.75.85 +49.12.76.153 +162.55.171.43 +159.69.241.187 +162.55.170.228 +162.55.171.32 +138.201.247.200 +159.69.84.185 +49.12.46.49 +159.69.40.46 +95.217.239.76 +159.69.41.36 +95.217.239.164 +116.202.106.77 +78.47.192.159 +116.202.106.138 +116.202.106.194 +82.202.237.245 +82.202.237.242 +82.202.237.243 +82.202.237.244 +37.9.6.34 +37.9.6.35 +37.9.6.36 +37.9.6.37 +37.9.6.38 +37.9.6.39 +37.9.6.40 +37.9.6.41 +37.9.6.42 +37.9.6.43 +37.9.6.44 +37.9.6.45 +37.9.6.46 +37.9.6.47 +37.9.6.48 +37.9.6.49 +37.9.6.50 +37.9.6.51 +37.9.6.52 +37.9.6.53 +37.9.6.54 +37.9.6.55 +37.9.6.56 +37.9.6.57 +37.9.6.58 +37.9.6.59 +37.9.6.60 +37.9.6.61 +37.9.6.62 + +``` + +
+ +### Проверка в бан листе + +Проверяем каждый IP по ссылке https://multirbl.valli.org/lookup/. При наличии IP в бан листе, согласно инструкции на сайте самого бан листа запрашиваем удаление из списка. + +У каждого сервиса свои требования. В каких то можно удалить IP из списка, в каких то нельзя. + +### Автоматическая проверка + +Каждый день происходит проверка списка всех IP адресов автоматически. При наличии в популярных блек-листах появляется сообщение в канале #deliverability. + +При наличии таких сообщений, необходимо сделать запрос в каждом блек-листе на исключение IP из списка. diff --git "a/internal-documentation/documentation-from-space/development/\320\237\321\203\320\261\320\273\320\270\320\272\320\260\321\206\320\270\321\217 Android SDK.md" "b/internal-documentation/documentation-from-space/development/\320\237\321\203\320\261\320\273\320\270\320\272\320\260\321\206\320\270\321\217 Android SDK.md" new file mode 100644 index 00000000..ececa6b2 --- /dev/null +++ "b/internal-documentation/documentation-from-space/development/\320\237\321\203\320\261\320\273\320\270\320\272\320\260\321\206\320\270\321\217 Android SDK.md" @@ -0,0 +1,44 @@ +## Настройка приватных ключей + +Создаем файл `~/.gradle/gradle.properties` и добавляем в него следующие записи: + +``` +ossrhUsername=1Swr8KZY +ossrhPassword=i8waV4jpanoWhvHVo1cLW8U1bbrDZ5Nc3Ukm9Re0R/Ca +signing_keyId=329C78F9 +signing_password=976431 +signing_secretKeyRingFile=~/.gradle/com.rees46.key.gpg +sonatype_rees46=1a52351fba7390 +sonatype_personaclick=1a528b6d287289 + +``` + +Файл подписи:` com.rees46.key.gpg.` + +## Сборка и отправка релиза + +В корне проекта вводим: + +`./gradlew publish` + +При успешной загрузке увидим соответствующую надпись: + +![img.png](./images/android-successful-download.png) + + ## Публикация релиза + +Открываем https://s01.oss.sonatype.org/. +Для авторизации вводим логин / пароль из файла `~/.gradle/gradle.properties` из полей `ossrhUsername` и `ossrhPassword`. +В левом меню нажимаем `Staging Repositories`. + +![img.png](./images/android-staging-repositories.png) + +Выбираем оба пакета и жмем кнопку `Close`, в модалке просто жмем `Confirm`. + +![img.png](./images/android-close.png) + +После этого ждем пару минут, нажимаем кнопку `Refresh`. Ждем, чтобы в колонке `Status` изменился на closed. Когда статус изменился, жмем кнопку `Release`. + +![img.png](./images/android-release.png) + +Все, спустя несколько часов новый пакет будет в https://mvnrepository.com/artifact/com.rees46/rees46-sdk и https://mvnrepository.com/artifact/com.personaclick/personaclick-sdk. diff --git "a/internal-documentation/documentation-from-space/development/\320\241\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260 \321\201\320\270\321\201\321\202\320\265\320\274\320\275\321\213\321\205 \321\201\320\276\320\261\321\213\321\202\320\270\320\271.md" "b/internal-documentation/documentation-from-space/development/\320\241\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260 \321\201\320\270\321\201\321\202\320\265\320\274\320\275\321\213\321\205 \321\201\320\276\320\261\321\213\321\202\320\270\320\271.md" new file mode 100644 index 00000000..f610faae --- /dev/null +++ "b/internal-documentation/documentation-from-space/development/\320\241\321\202\321\200\321\203\320\272\321\202\321\203\321\200\320\260 \321\201\320\270\321\201\321\202\320\265\320\274\320\275\321\213\321\205 \321\201\320\276\320\261\321\213\321\202\320\270\320\271.md" @@ -0,0 +1,106 @@ +## Запуск цепочки + +Очередь: `chain`, параметры очереди: `durable: true`. + +Тело запроса JSON: + +``` +{"id": "CHAIN_ID", "client_id": "CLIENT_ID", "rule_id": "RULE_ID", "args": {}} + +``` +## Запуск транзакционого сообщения + +Очередь: `transactional`, параметры очереди: `durable: true`. + +Тело запроса JSON: + +``` +{"id": "CAMPAIGN_ID", "client_id": "CLIENT_ID", "args": {}} +``` + +- `test` - флаг, что это тестовая отправка. При включении код письма не будет сгенерирован и отправка не попадет в статистику. По умолчанию false. +- `cc` - вторичные получатели письма, которым направляется копия. +- `bcc` - скрытые получатели письма, чьи адреса не показываются другим получателям. +- `files` - массив файлов приложенных как attach к письму, используется только для email кампаний. В массиве должно быть не больше 10 файлов и суммарный их размер не должен превышать 10 Мб. Объект файла: + - `filename` - имя файла во вложении; + - `content_type` - тип файла; + - `data` - бинарные данные в base64. + +## Вызов вебхука + +Очередь: `notification`, параметры очереди:` durable: true`. Тип сообщения: `webhook`. + +Тело запроса JSON: + +``` +{"type": "webhook", "url": "URL", "body": "String body data"} +``` + +Опциональные параметры тела запроса: + +- `shop_id` - при наличии id магазина, ответ на запрос по указанному урлу будет добавлен в лог системных сообщений. Событие: `request`, тип продукта: `webhook`. +- `headers` - хеш заголовков: `{key => value}` + +## Обработка YML + +Очередь: `yml`, параметры очереди`: durable: true`. + +Тело запроса JSON: + +``` +{"shop_id": SHOP_ID, "force": false} +``` + +## Уведомления + +Очередь: `notification`, параметры очереди:` durable: true`. Тип сообщения: `notification`. + +``` +{"type": "notification", "shop_id": SHOP_ID, "notification_type": "technical", "subject": "Subject", "message": "Message body", "list_id": "yml_error"} +``` +Где: + +- `notification_type` - тип уведомления. Уведомляет клиентов только подписанных на данный тип. Доступные значения: `technical` +- `subject` - заголовок уведомления +- `message` - текст уведомления +- `list_id` - код шаблона уведомления. Доступные значения: `yml_error`. + +## Системное событие + +Очередь: `notification`, параметры очереди: `durable: true`. Тип сообщения: `system`. + +``` +{"type": "system", "shop_id": SHOP_ID, "event": EVENT, "client_id": CLIENT_ID, "clients": CLIENTS, "category": CATEGORY, "label": LABEL, "value": VALUE, "date": DATE, "created_at": CREATED_AT} +``` + +Обязательные поля: `shop_id`, `event` . + +Если указано поле `clients` - оно в приоритете над `client_id`. + +События: + +- `client_left_segment` - клиент вышел из сегмента. + - Обязательные поля: `category`, `client_id` OR `clients` + - Дополнительные поля: `category`: Segment всегда статично, `label`: SEGMENT_ID ID сегмента, `value`: KEY_ID идентификатор процесса вставки (т.к. события в БД пишутся построчно, чтобы выбрать слепок клиентов при обработке сегмента) +- `client_into_segment` - клиент попал в сегмент. + - Обязательные поля: `category`, `client_id` OR `clients` + - Дополнительные поля: `category`: Segment всегда статично, `label`: SEGMENT_ID ID сегмента, `value`: KEY_ID идентификатор процесса вставки (т.к. события в БД пишутся построчно, чтобы выбрать слепок клиентов при обработке сегмента) +- `product_price_decrease` - цена на товар снижена. Данное событие срабатывает после обработки товара. + - Поля `client_id`, `clients`, `category` не указываются. + - Дополнительные поля: `items`: [ITEM_UNIQID] - массив товаров с которым произошло событие +- `product_available` - товар снова в наличии + - Поля `client_id`, `clients`, `category` не указываются. + - Дополнительные поля: `items`: [ITEM_UNIQID] - массив товаров с которым произошло событие + +## Обработка заказа + +Очередь: `order`, параметры очереди: `durable: true`. + +``` +{"type": "TYPE", "order_id": ORDER_ID, "params": PARAMS} +``` + +Типы: + +- `persist` - обработка заказа после создания из события push +- `import` - импорт заказов через HTTP API diff --git "a/internal-documentation/documentation-from-space/development/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260 Development \320\276\320\272\321\200\321\203\320\266\320\265\320\275\320\270\321\217 REES46.md" "b/internal-documentation/documentation-from-space/development/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260 Development \320\276\320\272\321\200\321\203\320\266\320\265\320\275\320\270\321\217 REES46.md" new file mode 100644 index 00000000..71e8c277 --- /dev/null +++ "b/internal-documentation/documentation-from-space/development/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260 Development \320\276\320\272\321\200\321\203\320\266\320\265\320\275\320\270\321\217 REES46.md" @@ -0,0 +1,323 @@ +## Ключ авторизации + +1. Генерируем SSH-ключ без пароля: + +```bash +ssh-keygen +``` + +2. Выводим содержимое публичного ключа: + +```bash +cat ~/.ssh/id_rsa.pub +``` + +3. Открываем настройки JetBrains Space: `Preferences -> Git Keys` и добавляем ключ. + +4. Добавляем приватный ключ к SSH-агенту: + +```bash +ssh-add -K ~/.ssh/id_rsa +``` + +--- + +## Установка зависимостей + +### PostgreSQL 14 + +#### Ubuntu 18.04: + +```bash +sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' && \ +wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - && \ +sudo apt update +``` + +#### Ubuntu 18.04–22.04: + +```bash +sudo apt -y install postgresql-14 postgresql-client-14 libpq-dev +``` + +#### macOS: + +```bash +brew install postgresql +createuser -s postgres +brew services start postgresql +``` + +Добавляем службу в автозапуск: + +```bash +mkdir -p ~/Library/LaunchAgents && \ +ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents && \ +launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist +``` + +Запускаем утилиту: + +```bash +sudo -u postgres psql +``` + +Если `psql` и `createuser` недоступны: + +```bash +echo 'export PATH=/opt/local/bin:/opt/local/sbin:$PATH' >> ~/.profile && source ~/.profile +``` + +Создаем юзера и даем права: + +```sql +CREATE USER rees46 WITH ENCRYPTED PASSWORD 'rees46'; +ALTER USER rees46 WITH SUPERUSER; +``` + +--- + +### Clickhouse 22.2 (macOS) + +```bash +brew tap clickhouse/clickhouse && brew install clickhouse@22.2 && brew services restart clickhouse +``` + +--- + +### Обновление сертификатов + +#### Ubuntu: + +```bash +sudo apt install ca-certificates +``` + +#### macOS: + +```bash +brew install ca-certificates +``` + +--- + +### Ruby (через RVM) + +```bash +curl -sSL https://get.rvm.io | bash -s stable && source ~/.profile +``` + +Если возникает ошибка SSL: + +```bash +curl https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer | bash -s stable +``` + +Устанавливаем Ruby 2.7.5: + +```bash +rvm install 2.7.5 +``` + +Устанавливаем `bundler`: + +```bash +gem install bundler -v 1.17.3 +``` + +#### macOS: ошибка `requirements_osx_brew_update_system` + +```bash +sudo rm -rf /Library/Developer/CommandLineTools +xcode-select --install +``` + +--- + +### ImageMagick 6 + +#### Ubuntu: + +```bash +sudo apt-get install -y imagemagick-6.q16 libmagickwand-dev +``` + +#### macOS: + +```bash +brew install shared-mime-info imagemagick@6 +``` + +--- + +### Node 16, NPM + +#### Ubuntu: + +```bash +curl -sL https://deb.nodesource.com/setup_16.x | sudo bash - +sudo apt -y install nodejs +node -v +``` + +#### macOS: + +```bash +brew install node@16 +node -v +``` + +--- + +## Настройка API проекта + +```bash +mkdir ~/Projects && cd ~/Projects +git clone ssh://git@git.jetbrains.space/rees46/dev/api-rails.git && cd api-rails +cp config/database.yml.example config/database.yml +cp config/secrets.yml.example config/secrets.yml +``` + +Редактируем `config/database.yml`: + +```yaml +development_clickhouse: + <<: *default_clickhouse +# <<: *default_clickhouse_pg +``` + +Добавляем в `/etc/hosts`: + +```bash +sudo bash -c "echo '127.0.0.1 dev.api.rees46.com' >> /etc/hosts" +``` + +```bash +bundle config set --local without production +bundle install +``` + +Если ошибка с `gem puma`: + +```bash +bundle config build.puma --with-cflags="-Wno-error=implicit-function-declaration" +``` + +Создаем базы: + +```bash +rake db:create +rake db:schema:load +rake clickhouse:create clickhouse:schema:load +RAILS_ENV=test rake db:create +RAILS_ENV=test rake clickhouse:schema:load -- --simple +``` + +Запускаем сервер: + +```bash +bin/server +``` + +--- + +## Настройка Dashboard проекта + +```bash +git clone ssh://git@git.jetbrains.space/rees46/dev/Dashboard.git && cd Dashboard +cp ../api-rails/config/database.yml config/database.yml +cp config/secrets.yml.example config/secrets.yml +``` + +Редактируем `config/database.yml` аналогично API. + +```bash +bundle install +npm i +rake db:seed +rails s +``` + +Открываем [http://localhost:3000](http://localhost:3000). Используйте `localhost`, иначе не сработает капча. + +--- + +## Создание и настройка магазина + +1. Регистрируемся и создаем магазин с: + + * URL: `https://demo.rees46.com` + * YML-файл: `https://demo.rees46.com/store/xml_rees46.xml` +2. Жмем "Настроить позже". +3. В API-консоли: + +```bash +cd ~/Projects/api-rails && rails c +Customer.first.update(role: 0) +Shop.find(SHOP_ID).async_yml_import +``` + +4. Продлеваем магазин через `http://localhost:3000/admin/shops`, ставим тариф `xl` и дату в будущее. + +--- + +## Расширенная настройка + +### ElasticSearch 6.8 (macOS) + +```bash +brew install elasticsearch@6 +brew uninstall --ignore-dependencies openjdk +brew install openjdk@17 +brew services restart elasticsearch@6 +launchctl load ~/Library/LaunchAgents/homebrew.mxcl.elasticsearch@6.plist +``` + +Проверка: + +```bash +curl http://localhost:9200/ +``` + +Изменение конфигурации: + +```bash +curl -XPUT "http://localhost:9200/_template/default?pretty" \ + -H 'Content-Type: application/json' \ + -d'{"settings": {"number_of_shards": 2, "number_of_replicas": 0}, "index_patterns": ["*"]}' +``` + +Сброс read-only: + +```bash +curl -XPUT -H "Content-Type: application/json" \ +http://localhost:9200/_all/_settings \ +-d '{"index.blocks.read_only_allow_delete": null}' +``` + +--- + +## API Микро-сервисы + +Требуются: + +* PHP 8.1+ +* RabbitMQ 3+ +* ElasticSearch 6.8 + +Установка зависимостей PHP: + +```bash +apt -y install php8.1 php8.1-cgi php8.1-dev php8.1-bcmath php8.1-mbstring \ +php8.1-curl php8.1-pgsql php8.1-xml php8.1-gmp php8.1-intl php-pear libevent-dev +pecl install event +``` + +Установка Composer: + +```bash +php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +php composer-setup.php --install-dir=/usr/local/bin --filename=composer +``` + +(Дальнейшие шаги — по README соответствующих сервисов.) diff --git "a/internal-documentation/documentation-from-space/development/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260 \321\202\320\265\321\201\321\202\320\276\320\262\320\276\320\263\320\276 \320\277\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217 React-Native.md" "b/internal-documentation/documentation-from-space/development/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260 \321\202\320\265\321\201\321\202\320\276\320\262\320\276\320\263\320\276 \320\277\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217 React-Native.md" new file mode 100644 index 00000000..40dded50 --- /dev/null +++ "b/internal-documentation/documentation-from-space/development/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260 \321\202\320\265\321\201\321\202\320\276\320\262\320\276\320\263\320\276 \320\277\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217 React-Native.md" @@ -0,0 +1,171 @@ +## Установка зависимостей + +Тестирование проводилось на macOS Catalina 10.15.7. + +1. **Клонируем проект и переходим в директорию:** + + ```bash + git clone ssh://git@git.jetbrains.space/rees46/dev/TestPushProject.git && cd TestPushProject + ``` + +2. **Устанавливаем Ruby 2.7.5:** + + ```bash + rvm install "ruby-2.7.5" + ``` + + Если при установке возникла ошибка, указываем пути к OpenSSL 1.1: + + ```bash + export PATH="/usr/local/opt/openssl@1.1/bin:$PATH" + export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" + export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" + export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig" + rvm reinstall "ruby-2.7.5" + ``` + +3. **Устанавливаем вспомогательные библиотеки:** + + ```bash + brew install node watchman + ``` + +4. **Устанавливаем зависимости для Node.js:** + + ```bash + npm i + ``` + +## Запуск приложения в iOS-эмуляторе + +1. **Устанавливаем CocoaPods:** + + ```bash + cd ios + bundle install + bundle exec pod install + ``` + + Если в процессе появилась ошибка, связанная с отсутствием Xcode: + + * Установите Xcode из App Store. + * Откройте Xcode → Preferences → Locations → выберите версию Xcode для `Command Line Tools`. + * После этого снова выполните: + + ```bash + bundle exec pod install + ``` + +2. **Ошибка в конце установки `pod install`:** + + Если видите сообщение об ошибке, добавьте в `Podfile`: + + ```ruby + pod 'Firebase', :modular_headers => true + pod 'FirebaseCoreInternal', :modular_headers => true + pod 'GoogleUtilities', :modular_headers => true + ``` + + Затем повторите установку: + + ```bash + bundle exec pod install + ``` + +3. **Запускаем эмулятор:** + + ```bash + cd .. && npm run ios + ``` + + При успешном запуске должно открыться новое окно терминала и запуститься приложение в эмуляторе. + +4. **Ошибка компиляции `FBReactNativeSpec.h` (iOS 12.0):** + + Если при сборке возникает ошибка: + + ``` + error: 'value' is unavailable: introduced in iOS 12.0 + ``` + + Необходимо заменить строку во всех `Pod`-файлах: + + ``` + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + ``` + + на: + + ``` + IPHONEOS_DEPLOYMENT_TARGET = 12.4; + ``` + + Замену потребуется делать после каждого запуска `bundle exec pod install`. + + Альтернативно — указать нужную версию iOS в настройках Xcode вручную. + +5. **Настройка `shop_id` и пути к API:** + + * Файл: `App.js` + * Путь к API можно изменить в: + `node_modules/@rees46/react-native-sdk/index.js` + +## Настройка Firebase + +1. Перейдите в [Firebase Console](https://console.firebase.google.com) и создайте новый проект. + +2. Укажите `Apple bundle ID`: + `org.reactjs.native.example.TestPushProject` + +3. На следующем шаге скачайте `.plist` и добавьте его в Xcode: + + * Откройте `ios/TestPushProject.xcodeproj` в Xcode. + * Перетащите файл `.plist` в структуру проекта. + +4. Закройте Xcode и выполните повторный запуск: + + ```bash + npm run ios + ``` + +## Запуск приложения в Android-эмуляторе + +1. **Установите Android Studio и SDK:** + + Скачайте [Command line tools only](https://developer.android.com/studio/index.html) (внизу страницы) и распакуйте в удобную директорию. + +2. **Создайте файл `android/local.properties`:** + + ```properties + sdk.dir=/path/to/sdk + ``` + +3. **Добавьте пути к SDK в `~/.zshrc`:** + + ```bash + export ANDROID_SDK_ROOT=/path/to/sdk + export PATH=$PATH:$ANDROID_SDK_ROOT/emulator + export PATH=$PATH:$ANDROID_SDK_ROOT/platform-tools + ``` + + Примените изменения: + + ```bash + source ~/.zshrc + ``` + +4. **Создайте эмулятор в Android Studio:** + + * Версия: Android 12.0 (Google Play), API Level 31 + + *(Если есть физическое устройство с включённым USB-дебагом — подключите по USB, эмулятор можно не создавать.)* + +5. **(Для Windows)** + + Пропишите переменные окружения с путями к SDK в системных настройках. + +6. **Запуск приложения:** + + ```bash + npm run android + ```