ТЗ склада FC
Товародвижение склада Уфа · сверено с кодом и дизайн-доками · 28.08.2026
0Фундамент
1Вход ✓
2Размещение ✓
3Три цикла ✓
4Отгрузка ФБС · строить
6Возвраты · строить
5ФФ/FBO · за контуром
0 Фундамент: две правды об одном товаре
- У товара два независимых источника истины: книга («сколько числится») и физика («где лежит»).
- Книга —
WarehouseStock. Её меняют только документы: приёмка, списание проданного, отгрузка, корректировка. Ни один скан книгу напрямую не двигает.
- Книга общая для всей DDS: её читают ~45 модулей (потребность, баланс, витрина WB). Вторая таблица остатков запрещена навсегда.
- Физика — иерархия короб → паллета → адрес. Её меняют только сканы людей через журнал операций. У каждого движения — человек, устройство, время.
- Ночная сверка сводит книгу и физику до штуки; расхождение — именной документ, не подгонка (механика — раздел 6а).
- Ничего не перемещается «просто руками»: каждое перемещение = скан. Подсказки ничего не бронируют — истина рождается в момент скана.
Карта склада — все потоки одной схемой
ВОРОТА
│ выгрузка россыпью («выгружен, не разобран»)
▼
[АПРОН — россыпь без адреса]
│ скан короба · 📌 план «Разбор машины» (носим пачками, правится руками)
▼ ┌ переоткрытие: россыпь доливается
[ПРИЁМКА-БУФЕР — паллета (LPN) на адресе] ◄────┘ на недобитую закрытую паллету
│
│ ЗАКРЫТИЕ = порция в КНИГУ (приход; товар продаётся с этой секунды)
│ каскад: направление? → «горит»? → отбор голодает? → резерв
│
├─ целая паллета ────────────────► [ОТБОР — ярус 1: берут руками]
├─ целая паллета ────────────────► [РЕЗЕРВ — ярусы 2–3: только техника,
│ стоит НАД своим отбором]
├─ короба хвоста (доливка) ──────► [РЕЗЕРВ — к своему товару, полные первыми]
├─ короба: мало у артикула / микс ► [ПОЛКИ — «короб = ячейка», берут руками]
└─ (позже) направление ──────────► [STAGING — минуя хранение, cross-dock]
ВНУТРИ ХРАНЕНИЯ — три потока, один рейс может нести все три:
1. ПОПОЛНЕНИЕ ПАЛЛЕТОЙ: РЕЗЕРВ ──вниз НАСОВСЕМ (ярус 2 → 1)──► ОТБОР
триггеры: порог отбора (✅) · дефицит волны до сборки (📌)
2. ПОПОЛНЕНИЕ КОРОБАМИ (📌): снять паллету резерва → 1–2 короба СВОЕГО
товара на полку / в паллету отбора → паллета назад на СВОЁ место
3. ПЕРЕСБОРКА (места, отбор не трогает): хвост 3/10 + хвост 4/12 →
одна паллета, донор целиком или никак, место свободно
ВЫХОД:
ОТБОР + ПОЛКИ + БУФЕР ── волна ФБС: ШТУКИ, только руками ──►
[ЛЕНТА — столы упаковки: стикер → короб поставки]
ПОГРУЗКА: скан каждого короба, «Отправить» при 100 % ──► МАШИНА / WB
└ передача поставки = РАСХОД КНИГИ
ВОЗВРАТ: WB → скан стикера → короб возвратов → годное в продажу,
брак → в брак (книга не трогается — она уже вернула при отмене)
Как читать карту.
- Книга двигается ровно в двух точках: приход — закрытие паллеты на приёмке; расход — передача поставки WB. Всё остальное — чистая физика, каждый переход = скан. (Третья точка — документы-корректировки: фантомы, брак, сверка.)
- Руки берут только с досягаемых мест: отбор (ярус 1), полки, буфер приёмки. Наверх — только техника с целой паллетой.
- Роль места — свойство адреса, не зона: каскад выбирает роль, топология превращает её в ярус (ярус 1 = отбор, выше = резерв). Полка — отдельный тип: «короб и есть ячейка».
- Правила зашиты в адрес и энфорсятся обработчиком: лимит артикулов (≤ 3), лимит штук на полке, просвет яруса, тип места.
- Каждое место — QR-табличка; каждая паллета — этикетка LPN из пула.
1 Вход: машина → приёмка → книга работает
До машины. Состав известен заранее: QR-этикетки предвыпуска на коробах (фабрика/ФФ) или печать на месте. В QR — только код, состав живёт в системе: этикетка не врёт при переупаковке.
- Выгрузка. Россыпь у ворот; неотсканированный короб = «выгружен, не разобран».
- Открыть паллету. На поддон вешается паллетная этикетка (LPN) — многоразовая табличка из пула. Два скана: этикетка + табличка места = «эта паллета (КТО) стоит здесь (ГДЕ)». Одно место = одна паллета. Клапан: паллет ровно столько, сколько мест размечено; кончились — приёмка штатно встаёт, россыпь ждёт.
- 📌 строитьПлан разбора — экран «Разбор машины». Прогноз по каждому артикулу: целых паллет → хвост в доливку → малокоробочные «→ полки». Приёмщик может перетасовать план руками (перекинуть короба на другую паллету) — терминал ведёт по правке. Режим: «подтащи разом все 12 коробов артикула X и сканируй подряд». Прогноз ≠ бронь: раскладка рождается сканами.
- Разбор. Скан короба → система выбирает паллету буфера: где этот товар уже лежит (моно-паллеты собираются сами), иначе свободный сектор-буква до лимита 3 артикулов; не влезает → отказ с подсказкой «поставь следующий поддон на место X». Неопознанный ШК — в сторону, в книгу не идёт; чужая машина — отказ; класть сверх расчёта — только явный повтор с подтверждением и следом в журнале расхождений.
- Сигнал закрытия — считает система после каждого короба: «паллета полная» (следующий не ляжет — доли основания) или «последний короб артикула в машине» (по невыгруженным этикеткам). Закрывает человек; неполная паллета — норма.
- Закрытие. Плёнка + скан: адрес НЕ отпускается, а порция немедленно проводится в книгу — товар продаётся с этой секунды, конца фуры не ждут. Дважды провести невозможно.
- Судьба паллеты — прямо в ответе закрытия: «в отбор» / «в резерв на S-04-07» / честный WAIT. Рохля видит адрес на экране.
Плюс: закрытую паллету на её же месте можно переоткрыть (доложить россыпь; проведённое под штампом). Приёмщик и рохля работают параллельно — гонки закрыты локами, повтор скана идемпотентен.
⚠вес паллеты не проверяется; нужен op «перевесить короб между паллетами буфера». ❓выпуск и пул паллетных этикеток (где печатаются, кто пополняет).
📌 решение 28.08 Вход запуска — переезды с ФФ, россыпью или паллетными местами БЕЗ QR: склад сам печатает этикетку на каждый короб на месте, состав рождается на разборе (скан ШК товара + кратность / пересчёт). Режимы приёмки без предвыпуска — главный путь запуска, не запасной.
2 Размещение: куда едет закрытая паллета работает
Каскад ЦЕЛОЙ паллеты (момент решения — закрытие; первое сработавшее побеждает):
- Уезжает? Направление (ФФ/FBO) → STAGING, минуя хранение. ⚠активируется только с контуром направлений — сегодня не срабатывает.
- «Горит» — сразу в отбор под горящие заказы: придёт вместе с волнами ФБС.
- Отбор голодает? Паллет товара на местах отбора меньше порога (дефолт 1) → на место отбора. По остаткам, без справочников скоростей.
- Резерв — свободное не-отбор место рядом со своим товаром по обходу; учитываются лимит артикулов, просвет яруса, полка исключена. Мест нет — честный WAIT «склад полон».
Ярусы каскад не делят — их делит топология: роль зашита в адрес (ярус 1 = отбор, выше = резерв), поэтому «в отбор» физически и значит «на первый ярус». Резерв размечен над своим отбором → пополнение с нулём пробега. Урезанный ярус защищён просветом; план такие ярусы не целит — туда только ручным сканом.
Каскад ХВОСТА (паллеты, которая полной не станет) — по коробам:
- Доливка — короба по одному на стоящие паллеты того же товара в резерве, «самые полные первыми»; носится рейсом по маршруту обхода. Новая машина сначала добивает старые дыры.
- Полка (ячейки) — 📌 28.08 критерий один: у артикула мало коробов (новинка или нет — безразлично) + микс-короба. Целая паллета сюда не попадает никогда. Путь — через паллету-тележку буфера. ⚠микс-короб на полку сегодня отвергается обработчиком — правка нужна; правило «мало коробов» — дописать (порог и база счёта — открыты).
- Остаток — паллетой на свободное место.
Хвосты не ждут следующей машины: пересборка сшивает полупустые паллеты в любой момент, в том числе разные товары в микс до лимита места; детектор — сигнал «пересборка освободит 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, полки, буфер. Терминология: пересборка — про хвосты (места), пополнение — про спрос (кормить отбор).
- Штучный спрос (волны ФБС). Паллета НЕ снимается «отщипнуть и вернуть» — она спускается в отбор насовсем и живёт там до осушения; один спуск обслуживает десятки заказов. Триггера два: порог отбора (✅ живёт) и 📌дефицит волны — ДО старта сборки задания «спусти паллету», сборка стартует когда всё досягаемо.
- Пополнение коробами 📌 — для мест, живущих коробами (полки, початые паллеты отбора): снять паллету резерва → 1–2 короба своего товара сканами → паллета назад на своё место. Механика сканов готова, нужен триггер и шаги в рейсе.
- Один рейс рохли может нести шаги всех потоков по общему маршруту 📌.
4 Отгрузка ФБС строить · дизайн готов
День одной строкой: заказы копятся → волна → резерв по коробам → докладка в поставку → стикеры в свой кэш → сборка по маршруту → лента → санация → передача (списание книги) → погрузка → машина.
⚠ критический путь Боевая запись в WB ни разу не включалась (WB_FBS_MODE=safe). Первый шаг — ручной прогон create → add → стикер → deliver на живом ключе (этап 0 дорожной карты; там же trbx/СЦ и штрафы 31.08).
4.1 Волна
- Кандидат — живой заказ с карточкой, склад привязан, ещё не в волне. Без карточки — в алерт.
- Ключ волны и поставки = склад WB × тип груза × кросс-граница. Сегодня один ключ, код мультиключевой: КГТ даст вторую дневную поставку, посты обязаны различать. Cutoff 17:30.
- Автосоздание: ≥ 300 кандидатов ИЛИ старейший ждёт 45 мин → волна ≤ 400 заданий; ≤ 2 невзятых; окно 08–22. Приоритет — дедлайн кС (рубеж 42 ч дороже всего).
- Резервирование раскладывает спрос по коробам под одним замком. Кандидаты — только доступные: проведённые, без направления, с досягаемых мест (📌 28.08: ярус 1 + полки + буфер; контрактное «ярус ≤ 2» правится). Порядок: отбор/полки → буфер → резерв-1; початые первыми, потом раньше приехавшие. Жёстких броней нет — конкурентность держат guarded-счётчики.
- Дефицит легален: волна уходит частичной; супервизору — экран дефицитов с таймером до 42 ч и решениями: провести порцию из буфера / отменить с оценкой штрафа / ждать. 📌 Спрос только с верхних ярусов ДО старта сборки порождает пополнение.
- Release — жёсткий порядок: поставка → докладка чанками по 100 (перед каждым — перепроверка живости: одно умершее задание валит чанк) → все стикеры в свой кэш → только теперь сборка. Гард 100 %: нет одного стикера — волна стоит (ретрай 5 мин, алерт 15). Дальше WB может лежать весь день — печать из кэша.
4.2 Отбор (сборщик, ТСД)
- «Взять в работу» — волна за сборщиком; второму «собирает Иван»; бросил на 20 мин — слетает сама.
- Маршрут по обходу: «иди к ячейке → сканируй КОРОБ → сканируй ТОВАР ×N», каждый скан = 1 штука; адрес и количество перепроверяются в момент показа шага.
- Не тот короб → «Это BX-0200, нужен BX-0123»; не тот товар → «НЕ ТОТ ТОВАР» + след. Сверка ШК товара обязательна всегда.
- «Нашёл меньше» → кейпад: физика правится сразу, недостача переигрывается на другой короб, строка в хвост маршрута этого же сборщика; след + задание пересчёта. Другого короба нет → дефицит к супервизору.
- «Короба нет вообще» → подтверждение сканом таблички ячейки, короб → PROBLEM, строка переигрывается.
- Выел в ноль → «короб пуст?» → расформирование, этикетка в пул; «нет» → пересчёт.
- Последняя строка → «ВОЛНА СОБРАНА → отвези тележку на ленту, пост 2».
4.3 Лента (упаковщик; пост = мини-ПК + сканер + принтер)
- Пост живёт машиной состояний: ЖДУ ТОВАР → МАТЧ → ПЕЧАТАЮ → ЖДУ КОРОБ. Волну оператор не выбирает — скан товара сам находит старейшее задание по всем собранным волнам. Такт: 2 скана на юнит, 0 тапов, ~20 секунд.
- Один открытый заказ на пост: пока стикер не наклеен и юнит не в коробе — товарные сканы глухо блокированы самой машиной состояний (иначе второй скан того же SKU сматчил бы соседний заказ = два живых стикера).
- Матч — единственная строго-онлайн операция («какому заказу ушёл стикер» — серверная истина): нет связи → «СТОП — НЕТ СВЯЗИ». Остальные сканы поста живут в офлайн-очереди.
- Печать из кэша; повтор скана НИКОГДА не печатает; перепечатка — кнопкой, со второй — причина, счётчик у супервизора.
- Положить в короб: скан короба поставки; сервер перепроверяет «заказ жив?». Отменён → «ОТОРВИ И УНИЧТОЖЬ» — подтверждение сканом обрывка стикера, юнит в лоток возврата.
- Завис 15 мин → заказ освобождается + обязательный «СТИКЕР УНИЧТОЖИТЬ» со сканом обрывка.
- «Нет задания на товар» (самый частый нештат) → жёлтый экран «в лоток возврата» — стационарный короб у поста.
- Короб полон → «закрыть короб» → авто-печать стикера КОРОБА WB → следующий. Один открытый короб на пост.
4.4 Передача и погрузка
- За 30–60 мин до cutoff — обязательная санация: ресинк отмен, отчёт «что выпало». Упакованное дропает только санация; продавцовская отмена по упакованному запрещена.
- «Передать в доставку» — только при свежей санации и закрытых коробах → передача WB → книга списывается единым документом (единственный расход по ФБС) → QR поставки.
- Списание сорвалось → авто-ретрай + красная плашка + алерт «окно завышенной витрины».
- Погрузка: скан каждого короба; «Отправить» = 100 % сканов + пустая очередь устройства.
- Не успели к cutoff — штатный ежедневный перенос хвоста в завтрашнюю поставку (закрытые короба не трогаются). Механика у WB — на дыме этапа 0.
4.5 Законы контура
- Порядок release не переставляется; волна не стартует без 100 % стикеров.
- Один открытый заказ на пост; один открытый короб на пост; повтор скана не печатает.
- Книга по ФБС двигается один раз — списанием после передачи; обнуление фантома — документом.
- Отмена WB бьёт мгновенно на каждом рубеже: спрос волны → alive-проверка на посту → санация.
- Белый список доступности в обе стороны: волна не видит направления (✅), рейсы не трогают короба волны (строится).
- Пик руками — только с досягаемых мест; дефицит сверху → пополнение ДО старта сборки.
- Деструктив подтверждается сканом (обрывок стикера, табличка ячейки) — Yes/No-модалки запрещены.
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 Открытые вопросы
- Этап 0 (дым): trbx/СЦ, механика переноса заданий, штрафы 31.08.
- Юнит со стикером при отмене — «не вынимаем» vs «вынуть + уничтожить» (рекомендация: не вынимаем).
- Подтвердить мульти-поставки per cargoType — «одна поставка в день» неточна.
- Значения таймаутов (имена ключей есть, значений нет).
- Строгость скана погрузки с первого дня (рекомендация: мягко 2 недели → жёстко).
- Отбор целым коробом одним сканом — в первый релиз? (~2 000 сканов/день экономии).
- ⚠Стоп-гейт автоволны у cutoff (волна на 400 за 40 мин до 17:30 = гарантированный перенос) — в дизайне не решён.
6 Возвраты строить · ~160 шт/день
- Отказ покупателя после передачи поставки: книга уже вернула единицу (+1), физически коробка едет. Система заводит «ожидание возврата» — список того, что должно приехать.
- Коробка приехала: скан стикера WB → нашли заказ → закрыли ожидание → в короб возвратов. Книга не трогается — она уже правильная.
- Короб возвратов проверяется и закрывается: годное → на полку и снова продаётся, брак → в брак.
- Отмены до передачи: не собирали — ничего; собрали — на полку; стикер наклеен — «не вынимаем», уедет и вернётся возвратом.
❓путь брака дальше (адрес, документ списания); сроки/эскалация зависших ожиданий. Из аудита: возврат без ожидания (legacy-хвост ФФ-эпохи приедет в первые недели), сверка «товар = стикер» вторым сканом (пересорт ПВЗ — штраф 100 %), нечитаемый стикер, вычет открытых ожиданий из пуша витрины, возвраты FBO коробами, модель «штуки вне короба».
6а · Сверка книга = физика — как задание 📌 28.08
Что это. Каждую ночь система сама складывает физику (сумму штук во всех коробах по каждому артикулу) и сравнивает с книгой. Ночью — склад спит, картина не движется. Человек участвует не в сверке, а в разборе результата.
- Ночной джоб считает разницу по каждому артикулу до штуки.
- Каждое расхождение — именной документ: артикул, книга, физика, разница, когда.
- 📌 Карточка «Расхождения» в центре «Задания»: по каждому видно, в каких коробах товар лежит, и решения — «пересчитать короб» (шаг рейса), «списать/оприходовать документом-корректировкой», «нашли причину» (операция-виновник из журнала).
- Разобранное закрывается с фамилией и причиной; неразобранные копятся и краснеют.
Слепые пятна, закрыть при постройке: незакрытая волна ночью = ложные расхождения (сверка исключает WIP); ошибку кратности сверка не видит (книга и физика врут одинаково) — лечится выборочными пересчётами коробов.
§ Сквозные законы (в любом новом коде)
- Книга одна. Книгу двигают только документы, физику — только сканы.
- Каждое перемещение — скан с человеком и временем; журнал только дописывается.
- Идемпотентность: каждый скан несёт uuid; повтор возвращает сохранённый ответ. Расход — только guarded UPDATE.
- Подсказка ≠ бронь. Истина в момент скана; устаревшая подсказка получает честный отказ.
- Правила живут в топологии и энфорсятся обработчиком, а не экраном.
- Резерв не ест ни приёмку, ни места отбора. Клапаны честно останавливают поток.
- Отказ — это ответ: с причиной и следующим шагом для человека в перчатках, не 500.
- Ночная сверка до штуки; расхождение — именной документ.