ТЗ склада FC

Товародвижение склада Уфа · сверено с кодом и дизайн-доками · 28.08.2026

0Фундамент 1Вход ✓ 2Размещение ✓ 3Три цикла ✓ 4Отгрузка ФБС · строить 6Возвраты · строить 5ФФ/FBO · за контуром

0 Фундамент: две правды об одном товаре

  1. У товара два независимых источника истины: книга («сколько числится») и физика («где лежит»).
  2. Книга — WarehouseStock. Её меняют только документы: приёмка, списание проданного, отгрузка, корректировка. Ни один скан книгу напрямую не двигает.
  3. Книга общая для всей DDS: её читают ~45 модулей (потребность, баланс, витрина WB). Вторая таблица остатков запрещена навсегда.
  4. Физика — иерархия короб → паллета → адрес. Её меняют только сканы людей через журнал операций. У каждого движения — человек, устройство, время.
  5. Ночная сверка сводит книгу и физику до штуки; расхождение — именной документ, не подгонка (механика — раздел 6а).
  6. Ничего не перемещается «просто руками»: каждое перемещение = скан. Подсказки ничего не бронируют — истина рождается в момент скана.

Карта склада — все потоки одной схемой

ВОРОТА
  │ выгрузка россыпью («выгружен, не разобран»)
  ▼
[АПРОН — россыпь без адреса]
  │ скан короба · 📌 план «Разбор машины» (носим пачками, правится руками)
  ▼                                            ┌ переоткрытие: россыпь доливается
[ПРИЁМКА-БУФЕР — паллета (LPN) на адресе] ◄────┘ на недобитую закрытую паллету
  │
  │ ЗАКРЫТИЕ = порция в КНИГУ (приход; товар продаётся с этой секунды)
  │ каскад: направление? → «горит»? → отбор голодает? → резерв
  │
  ├─ целая паллета ────────────────► [ОТБОР — ярус 1: берут руками]
  ├─ целая паллета ────────────────► [РЕЗЕРВ — ярусы 2–3: только техника,
  │                                   стоит НАД своим отбором]
  ├─ короба хвоста (доливка) ──────► [РЕЗЕРВ — к своему товару, полные первыми]
  ├─ короба: мало у артикула / микс ► [ПОЛКИ — «короб = ячейка», берут руками]
  └─ (позже) направление ──────────► [STAGING — минуя хранение, cross-dock]

ВНУТРИ ХРАНЕНИЯ — три потока, один рейс может нести все три:
  1. ПОПОЛНЕНИЕ ПАЛЛЕТОЙ: РЕЗЕРВ ──вниз НАСОВСЕМ (ярус 2 → 1)──► ОТБОР
     триггеры: порог отбора (✅) · дефицит волны до сборки (📌)
  2. ПОПОЛНЕНИЕ КОРОБАМИ (📌): снять паллету резерва → 1–2 короба СВОЕГО
     товара на полку / в паллету отбора → паллета назад на СВОЁ место
  3. ПЕРЕСБОРКА (места, отбор не трогает): хвост 3/10 + хвост 4/12 →
     одна паллета, донор целиком или никак, место свободно

ВЫХОД:
  ОТБОР + ПОЛКИ + БУФЕР ── волна ФБС: ШТУКИ, только руками ──►
      [ЛЕНТА — столы упаковки: стикер → короб поставки]
  ПОГРУЗКА: скан каждого короба, «Отправить» при 100 % ──► МАШИНА / WB
      └ передача поставки = РАСХОД КНИГИ

  ВОЗВРАТ: WB → скан стикера → короб возвратов → годное в продажу,
      брак → в брак (книга не трогается — она уже вернула при отмене)

Как читать карту.

  1. Книга двигается ровно в двух точках: приход — закрытие паллеты на приёмке; расход — передача поставки WB. Всё остальное — чистая физика, каждый переход = скан. (Третья точка — документы-корректировки: фантомы, брак, сверка.)
  2. Руки берут только с досягаемых мест: отбор (ярус 1), полки, буфер приёмки. Наверх — только техника с целой паллетой.
  3. Роль места — свойство адреса, не зона: каскад выбирает роль, топология превращает её в ярус (ярус 1 = отбор, выше = резерв). Полка — отдельный тип: «короб и есть ячейка».
  4. Правила зашиты в адрес и энфорсятся обработчиком: лимит артикулов (≤ 3), лимит штук на полке, просвет яруса, тип места.
  5. Каждое место — QR-табличка; каждая паллета — этикетка LPN из пула.

1 Вход: машина → приёмка → книга работает

До машины. Состав известен заранее: QR-этикетки предвыпуска на коробах (фабрика/ФФ) или печать на месте. В QR — только код, состав живёт в системе: этикетка не врёт при переупаковке.

  1. Выгрузка. Россыпь у ворот; неотсканированный короб = «выгружен, не разобран».
  2. Открыть паллету. На поддон вешается паллетная этикетка (LPN) — многоразовая табличка из пула. Два скана: этикетка + табличка места = «эта паллета (КТО) стоит здесь (ГДЕ)». Одно место = одна паллета. Клапан: паллет ровно столько, сколько мест размечено; кончились — приёмка штатно встаёт, россыпь ждёт.
  3. 📌 строитьПлан разбора — экран «Разбор машины». Прогноз по каждому артикулу: целых паллет → хвост в доливку → малокоробочные «→ полки». Приёмщик может перетасовать план руками (перекинуть короба на другую паллету) — терминал ведёт по правке. Режим: «подтащи разом все 12 коробов артикула X и сканируй подряд». Прогноз ≠ бронь: раскладка рождается сканами.
  4. Разбор. Скан короба → система выбирает паллету буфера: где этот товар уже лежит (моно-паллеты собираются сами), иначе свободный сектор-буква до лимита 3 артикулов; не влезает → отказ с подсказкой «поставь следующий поддон на место X». Неопознанный ШК — в сторону, в книгу не идёт; чужая машина — отказ; класть сверх расчёта — только явный повтор с подтверждением и следом в журнале расхождений.
  5. Сигнал закрытия — считает система после каждого короба: «паллета полная» (следующий не ляжет — доли основания) или «последний короб артикула в машине» (по невыгруженным этикеткам). Закрывает человек; неполная паллета — норма.
  6. Закрытие. Плёнка + скан: адрес НЕ отпускается, а порция немедленно проводится в книгу — товар продаётся с этой секунды, конца фуры не ждут. Дважды провести невозможно.
  7. Судьба паллеты — прямо в ответе закрытия: «в отбор» / «в резерв на S-04-07» / честный WAIT. Рохля видит адрес на экране.

Плюс: закрытую паллету на её же месте можно переоткрыть (доложить россыпь; проведённое под штампом). Приёмщик и рохля работают параллельно — гонки закрыты локами, повтор скана идемпотентен.

вес паллеты не проверяется; нужен op «перевесить короб между паллетами буфера». выпуск и пул паллетных этикеток (где печатаются, кто пополняет).

📌 решение 28.08 Вход запуска — переезды с ФФ, россыпью или паллетными местами БЕЗ QR: склад сам печатает этикетку на каждый короб на месте, состав рождается на разборе (скан ШК товара + кратность / пересчёт). Режимы приёмки без предвыпуска — главный путь запуска, не запасной.

2 Размещение: куда едет закрытая паллета работает

Каскад ЦЕЛОЙ паллеты (момент решения — закрытие; первое сработавшее побеждает):

  1. Уезжает? Направление (ФФ/FBO) → STAGING, минуя хранение. активируется только с контуром направлений — сегодня не срабатывает.
  2. «Горит» — сразу в отбор под горящие заказы: придёт вместе с волнами ФБС.
  3. Отбор голодает? Паллет товара на местах отбора меньше порога (дефолт 1) → на место отбора. По остаткам, без справочников скоростей.
  4. Резерв — свободное не-отбор место рядом со своим товаром по обходу; учитываются лимит артикулов, просвет яруса, полка исключена. Мест нет — честный WAIT «склад полон».

Ярусы каскад не делят — их делит топология: роль зашита в адрес (ярус 1 = отбор, выше = резерв), поэтому «в отбор» физически и значит «на первый ярус». Резерв размечен над своим отбором → пополнение с нулём пробега. Урезанный ярус защищён просветом; план такие ярусы не целит — туда только ручным сканом.

Каскад ХВОСТА (паллеты, которая полной не станет) — по коробам:

  1. Доливка — короба по одному на стоящие паллеты того же товара в резерве, «самые полные первыми»; носится рейсом по маршруту обхода. Новая машина сначала добивает старые дыры.
  2. Полка (ячейки)📌 28.08 критерий один: у артикула мало коробов (новинка или нет — безразлично) + микс-короба. Целая паллета сюда не попадает никогда. Путь — через паллету-тележку буфера. микс-короб на полку сегодня отвергается обработчиком — правка нужна; правило «мало коробов» — дописать (порог и база счёта — открыты).
  3. Остаток — паллетой на свободное место.

Хвосты не ждут следующей машины: пересборка сшивает полупустые паллеты в любой момент, в том числе разные товары в микс до лимита места; детектор — сигнал «пересборка освободит N мест». Неустранимый минимум (последняя паллета товара всегда неполная) — плата за моно-паллеты, под контролем сигнала.

Законы: резерв не занимает мест отбора (три слоя защиты); лимит артикулов — две ручки (настройка приёмки + max_sku каждого адреса, менять согласованно); «доливка к своему» — гарантия подсказки, обработчик пустит чужой короб до лимита (решить, ужесточать ли); короб с направлением неподвижен для рейсов ✅ a84719ad.

2а · Нештатные ситуации

Канон: отказ — это ответ с причиной и следующим шагом; клапаны честно останавливают поток; всё нештатное оставляет след.

ВходЧто происходитСтатус
1Мест приёмки нетКлапан: приёмка встаёт, россыпь ждёт; сигнал ведёт на вывоз
2Неопознанный коробПринят физически, в книгу не идёт, аналитика краснеет✅ · ❓ кто матчит
3Этикетка чужой машиныОтказ, короб в сторону⚠ перепривязки нет
4Нечитаемая этикеткаТолько выпуск новой⚠ перепечатки нет
5Кол-во ≠ этикеткеПредвыпуску доверяем; заявленное хранится для отчёта точности⚠ пересчёта нет
6Брак при разбореКнига умеет брак отдельной строкой⚠ операции «пометить» нет
7Закрыли раноПереоткрытие на её же месте, проведённое под штампом
8Короб не на ту паллету📌 op «перевесить»
9Обрыв связи / повторИдемпотентность по uuid
10НедовозЗакрытие плана: в книгу только факт со сканера
11Незаявленный товарСтрока «ожидалось 0»
РазмещениеЧто происходитСтатус
1Место занято / снятоОтказ с причиной, подсказка пересчитывается
2Выше просветаОтказ, другое место
3Отбор сытОтказ; override старшего со следом
4Резерв полонWAIT; паллета держит линию → сигнал → пересборка
5Устаревший шаг заданияОтказ шага, рейс не падает, план пересчитывается
6Паллета «в проходе»Авария: первая в очереди вывоза✅ детект
7Перемещение без сканаЛовит сверка и «в проходе»⚠ ревизии нет
8Бесхозный коробСкан покажет, где числится; вернуть доливкой/на полку⚠ флоу нет
9Габариты врутOverride + журнал + сигнал → правится справочник

3 Жизнь склада: центр «Задания» и три цикла работает

Рамка. Центр «Задания»: живые карточки — «Вывоз из приёмки» и «Пересборка хвостов» (+ заглушки «Отгрузка», «Ревизия»). План любого задания — список шагов «возьми → отвези → положи» по обходу зала (до 600, длиннее — партиями), считается от живого состояния и ничего не бронирует; устаревший шаг честно отказывает и не роняет остальные. Каждый шаг — те же операции, что сканы: путей мимо журнала нет. Назначения на человека нет — исполняет взявший. Сегодня исполнение — кнопкой консоли; сканы с ТСД — следующий этап (заложено без переделки).

Цикл 1 — Пополнение отбора. Правило одно («в отборе меньше порога паллет товара»), срабатывает при приёмке (свежая паллета вниз) и изнутри: место отбора выели до нуля → паллета резерва переставляется вниз теми же сканами (резерв над отбором — ноль пробега); сытый отбор скан отобьёт. 📌Карточки «Пополнение» в каталоге нет — добавить.

Цикл 2 — Пересборка. Три фазы одним планировщиком: поднять короба из прохода доливкой → сшить хвосты (самые пустые в самые полные, донор целиком или никак, миксы до лимита, опустевший донор расформирован — этикетка в пул) → поставить остатки паллетами. Не трогает: отбор, STAGING, паллеты приёмки как приёмники, микс-короба, направленные короба. Без неё полигон «кончился» на ⅔ заполнения.

Цикл 3 — Сигналы. Аналитика кричит сама, каждый сигнал ведёт на экран починки: «мест ≤ 5 %», «паллеты переполнены — врут габариты», «коробы без документа», «пересборка освободит N мест»; паллета на месте приёмки — штатная очередь, «в проходе» — авария, первой в списке.

3а · Мостик к отгрузке: как спрос достаёт товар

Руки берут только с досягаемых мест — ярус 1, полки, буфер. Терминология: пересборка — про хвосты (места), пополнение — про спрос (кормить отбор).

4 Отгрузка ФБС строить · дизайн готов

День одной строкой: заказы копятся → волна → резерв по коробам → докладка в поставку → стикеры в свой кэш → сборка по маршруту → лента → санация → передача (списание книги) → погрузка → машина.

⚠ критический путь Боевая запись в WB ни разу не включалась (WB_FBS_MODE=safe). Первый шаг — ручной прогон create → add → стикер → deliver на живом ключе (этап 0 дорожной карты; там же trbx/СЦ и штрафы 31.08).

4.1 Волна

  1. Кандидат — живой заказ с карточкой, склад привязан, ещё не в волне. Без карточки — в алерт.
  2. Ключ волны и поставки = склад WB × тип груза × кросс-граница. Сегодня один ключ, код мультиключевой: КГТ даст вторую дневную поставку, посты обязаны различать. Cutoff 17:30.
  3. Автосоздание: ≥ 300 кандидатов ИЛИ старейший ждёт 45 мин → волна ≤ 400 заданий; ≤ 2 невзятых; окно 08–22. Приоритет — дедлайн кС (рубеж 42 ч дороже всего).
  4. Резервирование раскладывает спрос по коробам под одним замком. Кандидаты — только доступные: проведённые, без направления, с досягаемых мест (📌 28.08: ярус 1 + полки + буфер; контрактное «ярус ≤ 2» правится). Порядок: отбор/полки → буфер → резерв-1; початые первыми, потом раньше приехавшие. Жёстких броней нет — конкурентность держат guarded-счётчики.
  5. Дефицит легален: волна уходит частичной; супервизору — экран дефицитов с таймером до 42 ч и решениями: провести порцию из буфера / отменить с оценкой штрафа / ждать. 📌 Спрос только с верхних ярусов ДО старта сборки порождает пополнение.
  6. Release — жёсткий порядок: поставка → докладка чанками по 100 (перед каждым — перепроверка живости: одно умершее задание валит чанк) → все стикеры в свой кэш → только теперь сборка. Гард 100 %: нет одного стикера — волна стоит (ретрай 5 мин, алерт 15). Дальше WB может лежать весь день — печать из кэша.

4.2 Отбор (сборщик, ТСД)

  1. «Взять в работу» — волна за сборщиком; второму «собирает Иван»; бросил на 20 мин — слетает сама.
  2. Маршрут по обходу: «иди к ячейке → сканируй КОРОБ → сканируй ТОВАР ×N», каждый скан = 1 штука; адрес и количество перепроверяются в момент показа шага.
  3. Не тот короб → «Это BX-0200, нужен BX-0123»; не тот товар → «НЕ ТОТ ТОВАР» + след. Сверка ШК товара обязательна всегда.
  4. «Нашёл меньше» → кейпад: физика правится сразу, недостача переигрывается на другой короб, строка в хвост маршрута этого же сборщика; след + задание пересчёта. Другого короба нет → дефицит к супервизору.
  5. «Короба нет вообще» → подтверждение сканом таблички ячейки, короб → PROBLEM, строка переигрывается.
  6. Выел в ноль → «короб пуст?» → расформирование, этикетка в пул; «нет» → пересчёт.
  7. Последняя строка → «ВОЛНА СОБРАНА → отвези тележку на ленту, пост 2».

4.3 Лента (упаковщик; пост = мини-ПК + сканер + принтер)

  1. Пост живёт машиной состояний: ЖДУ ТОВАР → МАТЧ → ПЕЧАТАЮ → ЖДУ КОРОБ. Волну оператор не выбирает — скан товара сам находит старейшее задание по всем собранным волнам. Такт: 2 скана на юнит, 0 тапов, ~20 секунд.
  2. Один открытый заказ на пост: пока стикер не наклеен и юнит не в коробе — товарные сканы глухо блокированы самой машиной состояний (иначе второй скан того же SKU сматчил бы соседний заказ = два живых стикера).
  3. Матч — единственная строго-онлайн операция («какому заказу ушёл стикер» — серверная истина): нет связи → «СТОП — НЕТ СВЯЗИ». Остальные сканы поста живут в офлайн-очереди.
  4. Печать из кэша; повтор скана НИКОГДА не печатает; перепечатка — кнопкой, со второй — причина, счётчик у супервизора.
  5. Положить в короб: скан короба поставки; сервер перепроверяет «заказ жив?». Отменён → «ОТОРВИ И УНИЧТОЖЬ» — подтверждение сканом обрывка стикера, юнит в лоток возврата.
  6. Завис 15 мин → заказ освобождается + обязательный «СТИКЕР УНИЧТОЖИТЬ» со сканом обрывка.
  7. «Нет задания на товар» (самый частый нештат) → жёлтый экран «в лоток возврата» — стационарный короб у поста.
  8. Короб полон → «закрыть короб» → авто-печать стикера КОРОБА WB → следующий. Один открытый короб на пост.

4.4 Передача и погрузка

  1. За 30–60 мин до cutoff — обязательная санация: ресинк отмен, отчёт «что выпало». Упакованное дропает только санация; продавцовская отмена по упакованному запрещена.
  2. «Передать в доставку» — только при свежей санации и закрытых коробах → передача WB → книга списывается единым документом (единственный расход по ФБС) → QR поставки.
  3. Списание сорвалось → авто-ретрай + красная плашка + алерт «окно завышенной витрины».
  4. Погрузка: скан каждого короба; «Отправить» = 100 % сканов + пустая очередь устройства.
  5. Не успели к cutoff — штатный ежедневный перенос хвоста в завтрашнюю поставку (закрытые короба не трогаются). Механика у WB — на дыме этапа 0.

4.5 Законы контура

4.6 Числа (стартовые, крутить по обкатке)

Волна: ≥ 300 или 45 мин · ≤ 400 · ≤ 2 невзятых · окно 08–22 · клейм слетает за 20 мин. Пост: таймаут 15 мин · ~20 с/юнит ≈ 1 260/пост/смену → 3 поста ≈ 3 500/день (на 4 000 нужен 4-й). Чанки по 100. Cutoff 17:30, санация за 30–60 мин. Офлайн-очередь: батчи ≤ 20, порог возраста — блок операций серверной истины.

4.7 Открытые вопросы

  1. Этап 0 (дым): trbx/СЦ, механика переноса заданий, штрафы 31.08.
  2. Юнит со стикером при отмене — «не вынимаем» vs «вынуть + уничтожить» (рекомендация: не вынимаем).
  3. Подтвердить мульти-поставки per cargoType — «одна поставка в день» неточна.
  4. Значения таймаутов (имена ключей есть, значений нет).
  5. Строгость скана погрузки с первого дня (рекомендация: мягко 2 недели → жёстко).
  6. Отбор целым коробом одним сканом — в первый релиз? (~2 000 сканов/день экономии).
  7. Стоп-гейт автоволны у cutoff (волна на 400 за 40 мин до 17:30 = гарантированный перенос) — в дизайне не решён.

6 Возвраты строить · ~160 шт/день

  1. Отказ покупателя после передачи поставки: книга уже вернула единицу (+1), физически коробка едет. Система заводит «ожидание возврата» — список того, что должно приехать.
  2. Коробка приехала: скан стикера WB → нашли заказ → закрыли ожидание → в короб возвратов. Книга не трогается — она уже правильная.
  3. Короб возвратов проверяется и закрывается: годное → на полку и снова продаётся, брак → в брак.
  4. Отмены до передачи: не собирали — ничего; собрали — на полку; стикер наклеен — «не вынимаем», уедет и вернётся возвратом.

путь брака дальше (адрес, документ списания); сроки/эскалация зависших ожиданий. Из аудита: возврат без ожидания (legacy-хвост ФФ-эпохи приедет в первые недели), сверка «товар = стикер» вторым сканом (пересорт ПВЗ — штраф 100 %), нечитаемый стикер, вычет открытых ожиданий из пуша витрины, возвраты FBO коробами, модель «штуки вне короба».

6а · Сверка книга = физика — как задание 📌 28.08

Что это. Каждую ночь система сама складывает физику (сумму штук во всех коробах по каждому артикулу) и сравнивает с книгой. Ночью — склад спит, картина не движется. Человек участвует не в сверке, а в разборе результата.

  1. Ночной джоб считает разницу по каждому артикулу до штуки.
  2. Каждое расхождение — именной документ: артикул, книга, физика, разница, когда.
  3. 📌 Карточка «Расхождения» в центре «Задания»: по каждому видно, в каких коробах товар лежит, и решения — «пересчитать короб» (шаг рейса), «списать/оприходовать документом-корректировкой», «нашли причину» (операция-виновник из журнала).
  4. Разобранное закрывается с фамилией и причиной; неразобранные копятся и краснеют.

Слепые пятна, закрыть при постройке: незакрытая волна ночью = ложные расхождения (сверка исключает WIP); ошибку кратности сверка не видит (книга и физика врут одинаково) — лечится выборочными пересчётами коробов.

§ Сквозные законы (в любом новом коде)

  1. Книга одна. Книгу двигают только документы, физику — только сканы.
  2. Каждое перемещение — скан с человеком и временем; журнал только дописывается.
  3. Идемпотентность: каждый скан несёт uuid; повтор возвращает сохранённый ответ. Расход — только guarded UPDATE.
  4. Подсказка ≠ бронь. Истина в момент скана; устаревшая подсказка получает честный отказ.
  5. Правила живут в топологии и энфорсятся обработчиком, а не экраном.
  6. Резерв не ест ни приёмку, ни места отбора. Клапаны честно останавливают поток.
  7. Отказ — это ответ: с причиной и следующим шагом для человека в перчатках, не 500.
  8. Ночная сверка до штуки; расхождение — именной документ.

Раздел 5 (вывоз коробами на ФФ/FBO) — за контуром решением 28.08; текст сохранён в рабочем файле как задел. Канонический файл: ~/Desktop/FC_ТЗ_ПОНИМАНИЕ.md (там же нештат целиком, бэклог решений §9 и аудит 44 пробелов §10). Дорожная карта: FC_свой_склад/FC_ДОРОЖНАЯ_КАРТА_v2.md.