Что это. Сервис, который каждый день сам решает «какой товар куда переставить» внутри складов Wildberries, отправляет задачи в кабинет WBcon и следит за их выполнением. CEO не одобряет задачи поштучно — только настраивает защитные правила и смотрит отчёт.
Единственная цель. Поднять индекс локализации с текущих 67% до 90%+. Чем выше локализация — тем дешевле логистика WB, выше выкуп, быстрее доставка.
Где живёт. Сервер timeweb (cron + Python). Данные — в нашей Supabase. Кабинет — в WBcon. Сводки — в Telegram @wookiee_alerts_bot.
Проблема, которую решаем. У Wookiee 920+ артикулов лежат на 23 рабочих складах WB по всей России. Когда покупатель из Новосибирска заказывает товар, который физически лежит в Коледино — WB везёт его 5 дней через всю страну и берёт с нас за это повышенный коэффициент тарифа (КТР) и сниженный коэффициент региональной приоритезации (КРП). Покупатель ждёт долго → выкуп падает. Карточка не попадает в ТОП регионального поиска → продаж меньше.
Что делает сервис. Каждый день автоматически считает: «вот этот товар лучше переставить из Коледино в Новосибирск, потому что там его всё равно покупают». Отправляет такие задачи в WBcon. Следит, чтобы за неделю индекс локализации (доля заказов с ближайшего склада) рос.
Контроль возвращает данные в алгоритм: какие пары (склад A → склад B) выполняются успешно, какие WB отклоняет, какие зависают. Это та самая «калибровка по факту», которая будет в Sub-project B.
Сервис общается с тремя внешними системами. Понимать кто кому хозяин — критично, иначе непонятно почему мы не можем просто «прийти и взять».
| Система | Чья | Что оттуда нужно | Можем ли писать? |
|---|---|---|---|
| Wildberries (сам маркетплейс) | WB | Источник всех данных. WB не отдаёт нам данные напрямую — только через свой API (медленный и ограниченный). | Только через стандартный API селлера. Перестановки — отдельно через WBcon. |
| Wildberries DB (89.23.119.253) | Сторонний подрядчик | Готовая агрегированная база: остатки по складам, заказы, движения, история. Подрядчик сам ETL-ит данные из WB и держит свою копию. | ТОЛЬКО ЧТЕНИЕ Подрядчик нам не разрешает писать. |
| WBcon (сторонний сервис) | Сторонний сервис, наш кабинет | Это система, через которую WB разрешает делать перестановки. Звонит на телефон при создании задачи. У нас 2 номера-кабинета: ООО ВУКИ + ИП Медведева. | ЧТЕНИЕ + ЗАПИСЬ Поставить новую задачу, удалить старую, посмотреть статус. |
| Supabase (наша) | Наша | Наш «мозг» — здесь хранятся снимки WBcon, итоги расчётов алгоритма, аудит всех POSTов, история индекса. | ЧТЕНИЕ + ЗАПИСЬ Полный контроль. |
Что это. Доля заказов, которые ушли с ближайшего к покупателю склада. Если покупатель из Новосибирска купил товар, который физически лежал в Новосибирске — это +1 к локализации. Если приехал с Коледино — 0.
Зачем поднимать.
Как сейчас. Колеблется около 67% последнюю неделю. Цель — 90%+. Каждая точка процента индекса = сотни тысяч рублей в месяц (точная цифра — задача Sub-project C).
| Дата | Индекс | SKU в выборке | Что произошло |
|---|---|---|---|
| 22 мая | 67.11% | 275 | Расширенная выборка |
| 23 мая | 67.28% | 201 | Перешли на core-выборку |
| 26 мая | 67.22% | 201 | Первый live-батч 483 POST (вручную) |
| 27 мая | 67.19% | 201 | |
| 28 мая | 67.16% | 201 | Cron запущен · 164 POST автономно |
Важно Колебание ±0.1 п.п. за неделю — это шум, не сигнал. Решения смотрим на горизонте 14–30 дней. Автопилот стартовал вчера.
Каждый день сервис проходит один и тот же цикл из 6 этапов. Все времена — по московскому времени.
Это сердце сервиса. Объясняю по шагам — как для человека, не как для разработчика.
Для каждой пары (SKU + размер + склад-донор + склад-получатель) сервис задаёт вопрос: «может, стоит переставить?». На 920 артикулах × ~6 размерах × 23 склада × 23 склада это потенциально миллион пар. Большинство отсеивается сразу — нет товара на доноре, нет смысла везти на получателя, не хватает квоты направления.
После первичного отсева остаётся 700–2500 живых кандидатов в день (зависит от того, сколько SKU «съехало» с целевой локализации за сутки).
Главная формула:
rank = feasibility × max(0, impact_рублей) × (1 + priority_bonus)
Три компонента:
«Доедет ли задача?» Произведение четырёх вероятностей:
policy_mult — пара складов разрешена? (1.0 если auto, 0.5 если manual, 0 если blocked)quota_stability — направление стабильное в истории?quota_fit — наша задача помещается в дневную квоту WB?success_rate — историческая успешность пары (по умолчанию 0.85, пока wb2_pair_outcomes не накопил)«Сколько мы заработаем/сэкономим, если этот SKU переедет?» Считается так:
current_loc (где сейчас процент локализации этого SKU)projected_loc (где будет, если переставим планируемое qty)«Насколько срочно тащить именно этот SKU вверх?» Плавный приоритет (без жёстких порогов):
Пример: SKU на 42% → bonus 2.28. На 88% → 0.02.
Это вторая защитная сетка: даже отранжированных кандидатов алгоритм разделяет по «дорожкам» в зависимости от текущей локализации SKU и приоритетности направления WB:
| Дорожка | Условие | Что значит |
|---|---|---|
| A | SKU <60% локализация + направление tier=high | Самое приоритетное — критично низкая локализация на горячем направлении |
| B | SKU 60–75% + tier=high | Подтянуть «середняка» на горячем направлении |
| C | SKU <60% + tier=medium | Низкая локализация на среднем направлении (~90% сегодняшних кандидатов сюда) |
| D | SKU 75–90% + tier=high | Дотянуть «хорошо» до «отлично» на горячем направлении |
| E | SKU 60–75% + tier=medium | Средний приоритет |
| F | Заблокирован / низкое направление / уже >90% | Не предлагаем |
В POST идут отсортированные по: (1) Новосибирск в конец (там высокая конкуренция за квоту, не блокируем остальные направления), (2) по убыванию rank-score. Топ-N (сейчас 500) реально отправляется в WBcon.
| Что | Где лежит | Кто меняет |
|---|---|---|
| Веса формулы (0.30 локализация, 0.20 выручка, …) | Код scoring.py | Будущий Sub-project B — автокалибровка |
| Пороги lanes (60%, 75%, 90%) | Код planner.py | Sub-project B |
| Список заблокированных складов | БД wbcon_constraints | CEO — UPDATE в БД |
| Cooldown 72ч | БД wbcon_constraints | CEO |
| Дневные лимиты (per-SKU 400, total 5000) | Код sync.py | CEO через обсуждение → правит код |
| candidate_limit=500 | Код sync.py | CEO — защитная заглушка первого дня |
Каждый день одна и та же воронка из 6 ступеней. Цифры в иллюстрации — типичные, в реальности зависят от дня (плюс-минус 30%).
| # | Ступень | Что отсевается и почему |
|---|---|---|
| 1 | Построение пар | Алгоритм не рассматривает пары: где на доноре нет товара, где донор и получатель совпадают, где у получателя уже хороший остаток, где направление закрыто WB. |
| 2 | Scoring + lane F | Кандидаты с заблокированными парами (politicy=blocked / direction_tier=low) уходят в lane F и не доходят до POST. |
| 3 | candidate_limit=500 | Жёсткая константа в sync.py:177. «Защитная заглушка первого дня». Берёт топ-500 по rank. Когда автопилот докажет стабильность — поднимем до 1500–2000. |
| 4 | Дневные лимиты | Не больше 400 шт одной модели в день (через все пары складов). Не больше 5000 шт всего. Лишнее переносится «на завтра» (но завтра алгоритм пересчитывает с нуля — это просто верхний потолок). |
| 5 | chrt_id resolve | Чтобы POST в WBcon прошёл, нужен chrt_id (внутренний ID размера в WBcon). 3 источника: колонка в БД (пока NULL), live-запрос в WBcon stocks (rate-limited), исторический кэш из wb2_task_outcomes (растёт сам). Сегодня покрытие ~35%, через 2 недели должно быть 70–90%. |
| 6 | POST в WBcon | Что осталось — реально летит в кабинет. Каждый запрос аудируется в wb2_task_outcomes: что отправили, что ответ, в какое время. Дальше задачу подхватывает WB и кладёт на исполнение склада. |
17 таблиц в Supabase. Делятся на 4 функциональные группы. Для каждой ключевой таблицы — что лежит, какие колонки, пример строки, какие срезы можно делать.
| Таблица | Что хранит | Строк |
|---|---|---|
wbcon_warehouses | Справочник 29 складов WB с их WBcon-ID | 29 |
wbcon_task_snapshots | Активные задачи WBcon — снимок на каждый цикл | ~2 500 |
wbcon_in_transit_snapshots | Товар «в пути» по парам складов | ~700 |
wbcon_quota_snapshots | Квоты направлений WBcon (сколько примет каждый склад) | ~200 |
wbcon_direction_snapshots | Снимки разрешённых направлений | ~1 500 |
wbcon_constraints | Защитные правила (см. §08) | 12 |
wbcon_task_snapshotsАктивные задачи WBcon. Колонки:
external_task_id — ID задачи в WBcon (например, 845)
normalized_status — нормализованный статус (active / in_transit / no_response)
nm_id, chrt_id — что за товар и размер
size_name — название размера ("S", "M")
src_id, dst_id — ID складов донора и получателя
src_name, dst_name — их названия
qty — сколько штук просим переставить
first_seen_at, last_seen_at — когда впервые увидели в WBcon и когда последний раз
Срезы которые можно делать:
dst_name='Краснодар' AND normalized_status='active'first_seen_at < now() - 7d AND normalized_status = 'no_response'SUM(qty) GROUP BY dst_name='Новосибирск'wbcon_in_transit_snapshotsТовар, который уже отправили, но ещё не доехал. Алгоритм использует это в формуле эффективного остатка (см. §05). Без этой таблицы он бы предлагал переставить одно и то же снова и снова.
| Таблица | Что хранит | Строк |
|---|---|---|
wb2_runs | 1 строка = 1 прогон алгоритма. Дата, статус, итоги в JSON. | ~10–15 в день |
wb2_candidate_moves | Каждый кандидат на перестановку с полной диагностикой scoring | 5 000+ |
wb2_rule_sets | Настройки алгоритма (cadence, thresholds) | 2 (1 active) |
wb2_candidate_movesЗдесь лежат ВСЕ кандидаты которые алгоритм когда-либо рассматривал — и принятые, и отброшенные. Это и есть «черный ящик» алгоритма наружу. Колонки:
id — уникальный ID кандидата
run_id — к какому прогону относится (FK на wb2_runs)
candidate_key — уникальный ключ (cabinet|article|size|src|dst)
article, nm_id, chrt_id, size_name — что за товар
src_warehouse_name, dst_warehouse_name — пара складов
lane — A/B/C/D/E/F (см. §05)
rank_score — итоговый ранг (feasibility × impact × priority)
expected_success_probability — вероятность что доедет
expected_localization_gain — на сколько вырастет локализация SKU (рубли/месяц)
score_features_json — ПОЛНАЯ диагностика scoring (см. ниже)
decision — selected / rejected / backlog / cooldown
planned_qty — сколько штук планируем переставить
decision_reason — почему такое решение
created_at — когда посчитан
Внутри score_features_json лежит scoring_diag — расшифровка каждого числа:
{
"impact": {
"price": 2122.12, // цена единицы
"current_loc": 48.9, // текущая локализация SKU
"projected_loc": 50.4, // прогнозируемая после перестановки
"monthly_orders": 45.2, // сколько заказов в месяц
"ktr_now": 1.2, "ktr_new": 1.1,
"krp_now": 2.05, "krp_new": 2.05,
"impact_ktr_rub": 361.0, // экономия логистики, ₽/мес
"impact_krp_rub": 0.0 // дополнительная выручка от КРП, ₽/мес
},
"feasibility": {
"policy_mult": 1.0, // разрешено
"quota_fit": 1.0, // помещаемся
"success_rate": 0.85, // историческая
"pair_history": [0, 0] // [успехов, попыток] — пока пусто
},
"priority": {
"projected_loc_pct": 100.0,
"bonus_primary": 0.0,
"bonus_secondary": 0.0
}
}
Срезы которые можно делать:
ORDER BY rank_score DESC LIMIT 20GROUP BY decision_reasonWHERE lane='A' GROUP BY nm_id HAVING COUNT(DISTINCT run_id::date) >= 5WHERE candidate_key=... ORDER BY created_at| Таблица | Что хранит | Строк |
|---|---|---|
wb2_task_outcomes | Аудит каждой операции POST/DELETE с полным request/response | 1 200+ |
wb2_run_log | Heartbeat + DB-lock каждого cron-этапа | ~10/день |
wb2_localization_history | Дневной снимок индекса локализации по каждому SKU | +201/день |
wb2_task_outcomesКаждая операция (POST новой задачи, DELETE устаревшей) пишет сюда строку. Это наш чёрный ящик — если что-то пошло не так, ищем здесь.
id — уникальный
cabinet_code — 'ooo' или 'ip'
external_task_id — ID задачи в WBcon (для POST=success)
candidate_move_id — FK на wb2_candidate_moves (откуда брали)
submitted_at, resolved_at — времена постановки и завершения
resolution — 'success' / 'unknown' / 'cancelled'
sku_loc_pct_before, sku_loc_pct_after — локализация SKU до/после
metadata_json — request, response, error в JSON
В metadata_json — полная история: что отправили, что получили, какая ошибка. Это и есть тот неявный кэш chrt_id — sync.py при следующих POSTах смотрит сюда «а постили ли мы такой SKU раньше».
Срезы:
GROUP BY (metadata_json->>'op'), resolutionWHERE resolution='wb_rejected'wb2_localization_history+201 строка в день (по SKU из core-выборки). Поля:
snapshot_date — дата
cabinet_code — ooo / ip
nm_id — SKU
loc_pct — индекс локализации в этот день
orders_period — заказы за расчётный период (для веса)
Это и есть та таблица, на которой будут все графики «индекс растёт?». Из неё считается средневзвешенный индекс по кабинету. И именно здесь Sub-project C будет искать каузальную связь «наши действия → рост».
Все живут в wbcon_warehouses. Разбиты по регионам (региональная группировка — для понимания, в БД её пока нет):
Двойники : Питание — отдельный режим WB, в перестановках не используется (заблокирован в защитных правилах).
wbcon_constraints«Не навреди» — главный принцип. Правила версионируются (effective_from / effective_to), менять = политическое решение, не эксперимент алгоритма.
| Правило | Значение | На человеческом |
|---|---|---|
blocked_to_warehouses |
Коледино, Подольск, СПБ Шушары, Шушары, Казань, Питание | Перегружены — никогда не отправляем сюда товар, даже если по математике выгодно |
blocked_from_warehouses |
Екатеринбург, Владимир, Новосемейкино, Самара, Пенза, Подольск | С этих складов забирать через автомат нельзя — пойдут на ручной разбор |
high_competition_warehouses |
Новосибирск, Екатеринбург, СПБ, Казань | Эти склады нарасхват — режем квоту, не лезем впереди других продавцов |
cooldown_hours_72 |
72 часа | Если вчера предложили пару (SKU + склад-донор) — следующие 3 суток повторно не предложим |
no_response_reserve_hours_23 |
23 часа | Задачи без ответа считаем «возможно едут» 23 часа после создания (потом списываем) |
in_transit_confidence_0_9 |
0.9 | Товар в пути считаем как 90% — 10% риск что не доедет (отмены, потери) |
safe_rate_per_phone_per_second_3 |
3 req/s | Безопасная скорость наших запросов к WBcon на номер |
rate_limit_429_threshold_4_5 |
4.5 req/s | Выше этого WBcon начнёт отдавать 429 (rate limit) |
default_daily_capacity_units_300 |
300 шт | Дневной потолок единиц для одного направления (когда квота направления неизвестна) |
default_capture_factor_0_6 |
0.6 | Можем занять до 60% квоты направления одной задачей — остальное оставляем другим |
wb2_rule_setsАктивный набор: phase-a-default. Это не правила WB, а наши тайминги:
{
"cycle_evening_msk": "22:00", ← вечерний расчёт по МСК
"cycle_morning_check_msk": "07:00", ← утренняя перепроверка
"cycle_post_msk": "09:00", ← окно WBcon открывается
"cycle_tracker_msk": ["12:00","15:00","18:00","21:00"],
"cycle_digest_msk": "21:30", ← вечерний дайджест
"morning_check_drift_threshold": 0.2, ← молчим если < 20% drift
"morning_check_replan_if_invalid_pct_gt": 0.5, ← URGENT если > 50%
"digest_threshold_tech_fail_pct": 20, ← порог tech-fail для дайджеста
"digest_threshold_wb_reject_pct": 5, ← порог отказов WB
"duplicate_alert_window_hours": 24, ← окно дедупа URGENT
"lock_ttl_minutes": 60, ← макс длительность DB-lock
"hanging_task_ttl_days": 7 ← когда списать «зависшую» задачу
}
Бот: @wookiee_alerts_bot (общий с другими сервисами Wookiee). 6 типов сообщений, переписаны на нормальный русский, без жаргона.
Файл /etc/cron.d/wb-loc-2 на сервере timeweb. TZ=Europe/Moscow в шапке файла.
| Время МСК | Этап | Cron expression |
|---|---|---|
| 22:00 | Вечер — построить план | 0 22 * * * |
| 07:00 | Утренняя перепроверка | 0 7 * * * |
| 09:00 | POST batch | 0 9 * * * |
| 12:00, 15:00, 18:00, 21:00 | Трекер | 0 12,15,18,21 * * * |
| 21:30 | Дайджест | 30 21 * * * |
| каждый час :30 | Сторож (cleanup + heartbeat) | 30 * * * * |
Сейчас Запущен только кабинет ООО ВУКИ. Кабинет ИП Медведева — на паузе по решению CEO.
WBcon ужесточил лимит на эндпоинт остатков — пустые ответы при превышении 4 req/window.
Обход: исторический кэш chrt_id. Сегодня ~35% покрытия, растёт с каждым POST.
Колонка есть (миграция 013), но планировщик пока её не заполняет — резолюция на POST-этапе.
План: в evening-этапе подмешивать chrt_id из кэша.
«Защитная заглушка» в sync.py. Сейчас режет ~282 кандидата из плана.
План: поднять до 1500–2000 после 2–3 успешных автономных циклов.
Cron работает только для ООО.
Когда включать: по решению CEO.
Считает «процент невалидных» — без разбора по причинам.
План: разложить причины в Sub-project B.
Не отвечаем на вопрос «индекс вырос благодаря нам или сам».
План: Sub-project C — отдельный движок атрибуции.
| Фаза | Что добавляет |
|---|---|
| B · Pair statistics | Таблица wb2_pair_outcomes копит «сколько раз пара (склад A→B) завершалась успехом». Алгоритм начинает учитывать реальные success-rate, а не догадку 0.85. |
| C · Causal attribution | Раскладывает прирост индекса по причинам: вклад наших действий vs алгоритм WB vs сезонность. Отвечает на главный вопрос «работает ли сервис». |
| D · LLM agents | Еженедельный обзор по pair_outcomes. Утренний дайджест CEO на человеческом языке («что произошло вчера, на что обратить внимание»). |
| E · Auto-stop | Логика «когда хватит». Если индекс на плато 14 дней — снижаем интенсивность. Если ROI падает — стоп. |
Сейчас всё что видит CEO — это Telegram-сообщения. Добавляем раздел в Wookiee Hub: hub.os.wookiee.shop/wb-localization.
В левой навигации Hub появляется новый раздел «WB Локализация» с 6 подпунктами:
Выберите раздел в боковом меню или используйте быстрые ссылки ниже ↓
Дальше — описание каждого экрана и mockups.
Это первая итерация. Будем дорабатывать. Каждый экран — отдельная подстраница раздела.
Цель. Один экран, на который CEO смотрит раз в день и понимает: всё в порядке или нет. Если красная лампочка — куда кликнуть.
Следующее обновление трекером в 21:00 МСК
wb2_localization_history (avg по дням)wb2_task_outcomes за сегодня по resolutionwb2_run_log по stageЦель. Понять «почему сегодня всего 164, а не 700». Кликнуть на любую ступень и увидеть список отсеянных кандидатов.
| Ступень | Кандидатов | Доля | Действие |
|---|---|---|---|
| 🧮 Все возможные пары | ~миллион | — | (не показывается) |
| 🎯 Живые кандидаты | 782 | 100% | смотреть → |
| 📊 После scoring (lane A–E) | 782 | 100% | по lanes → |
| 🚦 candidate_limit=500 | 500 | 64% | 282 отсев → |
| ⚡ После дневных лимитов | 466 | 60% | 34 отсев → |
| 🔑 С разрешённым chrt_id | 164 | 21% | 302 ждут → |
| ✅ Уехало в WBcon | 164 | 21% | по складам → |
| Модель/размер | Откуда → куда | Шт | Loc | Rank | Lane |
|---|---|---|---|---|---|
| Wendy чёрный, S | Коледино → Краснодар | 50 | 42% → 67% | 2 450 | A |
| set_moon2 белый, S | Тула → Новосибирск | 28 | 50% → 100% | 2 030 | C |
| Carmen бежевый, M | Электросталь → Казань | 28 | 48% → 73% | 1 880 | A |
| ... ещё 7 строк ... | |||||
wb2_candidate_moves по decision + wb2_task_outcomes по resolutionGROUP BY lane FROM wb2_candidate_moves WHERE run_id=46ORDER BY rank_score DESC LIMIT 10 + расшифровка из score_features_jsonЦель. Полный лог всех POST/DELETE с фильтрами. Когда что-то висит — посмотреть. Когда склад жалуется на «задачу X» — найти.
| Время | Задача | Модель/размер | Откуда → куда | Шт | Статус |
|---|---|---|---|---|---|
| 28.05 14:52 | #845 | Wendy/black S | Коледино → Краснодар | 50 | ✅ выполнено |
| 28.05 14:52 | #844 | set_moon2/white S | Тула → Новосибирск | 28 | 🚛 в пути |
| 28.05 14:52 | #843 | Carmen/beige M | Электросталь → Казань | 28 | ❌ WB отменил |
| 28.05 14:51 | #842 | Alice/black S | Подольск → СПБ | 36 | ✅ выполнено |
| ... показано 4 из 812 ... | |||||
Клик по строке → детали: full request/response, время WBcon-резолюции, ссылка на кандидата.
wb2_task_outcomes с joins на wb2_candidate_moves и wbcon_warehousesmetadata_json полностьюcabinet_code, created_at, (metadata_json->>'op')Цель. Главный вопрос «работает ли сервис». График индекса по дням, разбивка по складам и SKU, выявить узкие места.
| Склад | Индекс | Δ 7д |
|---|---|---|
| Краснодар (Тих.) | 78% | +1.2 |
| Невинномысск | 74% | +0.4 |
| Новосибирск | 71% | −0.3 |
| Тула | 68% | 0 |
| Коледино | 62% | −0.8 |
| Электросталь | 59% | +0.2 |
| SKU | Индекс | В очереди |
|---|---|---|
| Gimelim plus, XL | 32% | 12 |
| Wendy чёрный, XS | 38% | 8 |
| Zella купальник, M | 41% | 14 |
| Carmen бежевый, L | 44% | 6 |
| set_moon белый, XL | 46% | 5 |
Зелёная линия — индекс. Синие точки — дни с POST'ом.
⓵ В Phase C добавим разложение «причина роста: мы / WB / сезон»
wb2_localization_history по дням, средневзвешенныйwb2_localization_history с маппингом по складам через snapshotcurrent_loc < 50% AND есть кандидаты в open queueЦель. CEO видит и при необходимости меняет: список заблокированных складов, cooldown, дневные лимиты. История изменений.
| Тип | Список складов | Действует с | |
|---|---|---|---|
| 🚫 Куда не ставим | Коледино, Подольск, СПБ Шушары, Шушары, Казань, Питание | 22 мая 2026 | ✎ изменить |
| ⚠️ Откуда — ручной разбор | Екатеринбург, Владимир, Новосемейкино, Самара, Пенза, Подольск | 22 мая 2026 | ✎ изменить |
| 🔥 Высокая конкуренция | Новосибирск, Екатеринбург, СПБ, Казань | 22 мая 2026 | ✎ изменить |
| Лимит | Значение | Зачем |
|---|---|---|
| Cooldown пары (SKU + донор) | 72 часа | Не предлагаем повторно 3 суток |
| Per-SKU дневной лимит | 400 шт | Одной модели не больше 400 шт/день |
| Total дневной лимит | 5 000 шт | Всего за день не больше 5 000 |
| candidate_limit (заглушка) | 500 | Топ-500 кандидатов идут в POST. ⚠️ Защитная заглушка. |
| In-transit confidence | 0.9 | 10% риск что товар «в пути» не доедет |
22:00 план → 07:00 перепроверка → 09:00 POST → трекер каждые 3ч → 21:30 дайджест
| Когда | Кто | Что |
|---|---|---|
| 22 мая | migration 009 | Создан изначальный набор из 12 правил |
| — пока единственная запись — | ||
wbcon_constraints WHERE effective_to IS NULL — все активныеeffective_to NOT NULLeffective_from=now(), старую закрываем; шлём Telegram «правило X изменено» с кнопкой rollbackЦель. Технический экран. Когда что-то не сработало — посмотреть лог. Когда нужно ручное вмешательство — кнопки запуска этапов.
| Время | Этап | Статус | Деталь |
|---|---|---|---|
| 28.05 18:30 | cleanup | ✓ | 0 stale locks |
| 28.05 18:00 | tracker | ✓ | обновлено сообщение msg_107 |
| 28.05 15:00 | tracker | ✓ | 87 done / 65 exec |
| 28.05 14:52 | post | ✓ | 164 POST / 124 DELETE |
| 28.05 14:40 | post | ✗ | WBconRequestError 503 — retry |
| 28.05 13:38 | morning | ✓ | drift 18% |
| 28.05 13:36 | evening | ✓ | 782 кандидата |
Только если что-то сломалось и нужно принудительно перезапустить:
| Дата | Тип | Сообщение |
|---|---|---|
| 28.05 14:40 | POST fail | WBcon 503 |
| — нет других — | ||
wb2_run_log по каждому stageSELECT * FROM wb2_run_log ORDER BY started_at DESC LIMIT 20WB_LOC2_POST_DISABLED=1 на сервере + сообщение в Telegramwb2_run_log WHERE stage='alert_dedup'Это первая итерация. Доработаем по ходу. Главные открытые вопросы: