Runtime и потоки данных
Жизненный цикл синхронизации, ответа и QR-отправки.
Синхронизация App Feedback
Worker просыпается каждые 60 секунд, но фактический период опроса хранится в
FeedbackSetting. После сбоя следующая попытка планируется примерно через пять
минут. Lease истекает через десять минут, если процесс аварийно завершился.
Первый успешный запуск импортирует до 15 последних отзывов каждого магазина как
baseline. Дальше Apple читает перекрывающееся окно 50 отзывов, Google — всё
доступное недавнее API-окно. Перекрытие безопасно: записи обновляются по паре
(integrationId, externalReviewId).
После основного Apple/Google запроса worker также точечно проверяет внешние ответы для ограниченного числа недавних неотвеченных отзывов. Ответ, опубликованный вне Customer Support, таким образом попадает в локальное состояние.
Публикация ответа
- Server Action проверяет
feedback.reply. - Локальное состояние ответа атомарно меняется на
SENDING. - Создаётся append-only попытка
FeedbackReply. - Provider adapter вызывает Apple или Google вне длинной DB-транзакции.
- Текущий ответ и попытка получают итоговый статус.
- Ошибка переводит ответ в
FAILED; его можно отправить повторно.
Apple может принять ответ, но оставить его в PENDING. Это не равнозначно
ошибке и не должно автоматически менять внутренний workflow.
QR Feedback
Публичный token содержит 256 бит случайности и не раскрывает ID entity в URL. Один source host может создать не более трёх успешных отзывов за 10 минут по всем QR-кодам. Сырой IP не хранится — используется HMAC-хэш.
Для оценок 8–10 после успешной отправки может появиться явная кнопка Google Maps, если администратор настроил trusted HTTPS URL. Автоматического redirect нет.
Аналитика
Dashboard выполняет агрегаты в PostgreSQL и не загружает все отзывы в браузер. QR-аналитика включает средние оценки за 7/30 дней, динамику, распределение, объём и сравнение entities. Удалённые записи исключаются из всех агрегатов.

