feat: align project with OZON Track 3 official specification

- Fix critical parameters: min dimensions 10×10×2 mm (was 10×10×10)
- Fix roundness threshold: K ≥ 0.7 (was 0.8)
- Add input_info analysis document (INPUT_INFO_ANALYSIS.md)
- Update Hero: new title, badges (Min 10×10×2, K≥0.7→D, C priority), proof-line
- Add CurrentProofCard summary block: Category/Command/Target/Why (cyan border)
- Add CPriorityExplanation component (orange card, dedicated section)
- Update all docs: README, DEMO_SCRIPT (7-min timing), JURY_QA, SUBMISSION_CHECKLIST
- Update tests: 16/16 passed under new parameters
- Update 3D twin: dynamic DIMENSION_LIMITS display
- Update criteria cards: roundness ≥ 0.7
- Tested: build OK, Docker OK, domains OK (arhipovdan.ru, www, ai-shorts.ru)
This commit is contained in:
root
2026-07-04 13:09:49 +02:00
parent e0a655db4f
commit 17c37c2580
17 changed files with 709 additions and 29 deletions

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ vite.config.d.ts
.env
.env.*
npm-debug.log*
input_info/extracted/

View File

@@ -44,6 +44,29 @@ A → подающий конвейер → накопитель → CV/laser/ul
- Vitest для доменных тестов
- Docker + nginx (production static hosting)
## input_info
Проект разработан в соответствии с официальной постановкой задачи OZON Tech Track 3.
**Использованные материалы:**
- `Постановка_Задача_3_сжато_2.pdf` — полная постановка задачи (правила классификации, схема участка, критерии оценки)
- `doc-1783009942.pdf` — схема рабочей зоны с размерами A/B/C/D
- `doc-1783011400.pdf` — критерии оценки Track 3 (матрица баллов)
- `doc-1782987706.zip` → STEP модели тестовых товаров (11 шт)
- `doc-1782987733.zip` → STL модели тестовых товаров (11 шт)
**Тестовый набор товаров:**
Цилиндр, Шлем, Бутылка, Мешок, Тарелка, Короб 400×400×300, ЛанчБокс, Короб 300×200×200, Пуфик, Ручка, Моющее средство.
**Параметры классификации (согласно постановке):**
- Min dimensions: **10×10×2 мм**
- Max dimensions: 450×320×320 мм
- Roundness threshold: K ≥ **0.7**
- Conveyor speed: 1.00 м/с
- C-priority: габариты проверяются первыми
Подробный анализ: `docs/INPUT_INFO_ANALYSIS.md`
## Как открыть демо
Публично:
@@ -129,7 +152,7 @@ curl -I https://www.arhipovdan.ru/
- `normal_flow` — обычный поток B/C/D.
- `oversized_item` — max dimensions нарушены, маршрут C.
- `round_object` — габариты проходят, roundness >= 0.8, маршрут D.
- `round_object` — габариты проходят, roundness >= 0.7, маршрут D.
- `c_priority` — негабарит + круглый → только C (приоритет габаритов).
- `boundary_dimensions` — проверка min/max границ.
- `close_items` — предупреждение spacing/queue, последовательная обработка.
@@ -150,9 +173,9 @@ curl -I https://www.arhipovdan.ru/
Границы MVP:
- min: width >= 10 мм, depth >= 10 мм, height >= 10 мм;
- min: width >= 10 мм, depth >= 10 мм, height >= 2 мм;
- max: width <= 450 мм, depth <= 320 мм, height <= 320 мм;
- roundness threshold: 0.8 (K = r_in / r_out);
- roundness threshold: 0.7 (K = r_in / r_out);
- conveyor target speed: 1.00 м/с (close_items: 0.75 м/с).
## Исполнительная часть

View File

@@ -2,12 +2,27 @@
Open https://arhipovdan.ru/ (или http://127.0.0.1:3100/).
Страница — product demo: Hero → Demo → Storyline → Scenarios → Criteria → Engineering Details.
Страница — product demo: Hero → Demo → Storyline → Scenarios → C-priority → Criteria → Engineering Details.
## 30-Second Pitch
«Мы сделали инженерную симуляцию сортировочной ячейки OZON с 3D digital twin. Полный цикл: detection → classification → command → routing. Товар физически уходит в B/C/D. Physics engine не используем — motion по state machine, демо предсказуемо.»
## 7-Minute Structure
Рекомендуемый тайминг для защиты (максимум 7 минут):
- **0:00–0:20** Что это за система? ПАК предварительной сортировки, полный цикл A → CV → B/C/D.
- **0:20–0:45** Полный контур: Detection → Classification → Command → Actuator → Route.
- **0:45–1:30** Категория B: габариты проходят, нет круга, зелёный маршрут в основной сортировщик.
- **1:30–2:15** Категория C: негабаритный товар, оранжевый маршрут в roll-cage C.
- **2:15–3:00** Категория D: габариты проходят, но круг в сечении (K ≥ 0.7), фиолетовый маршрут в roll-cage D.
- **3:00–3:45** C-priority: негабаритный + круглый → всё равно C (приоритет габаритов).
- **3:45–4:30** Low confidence и fault: rule-based fallback, FAULT состояние, EMERGENCY_STOP.
- **4:30–5:30** Engineering Details: timeline, PID, sensors, event log, 3D capability check.
- **5:30–6:30** Критерии OZON и метрики: cycle time, устойчивость, воспроизводимость.
- **6:30–7:00** Ограничения MVP и развитие: real CV, physics engine, WebSocket телеметрия.
## 3-Minute Demo
1. На первом экране укажите Hero: что это за система и цепочку Detection → Classification → Command → Routing.

470
docs/INPUT_INFO_ANALYSIS.md Normal file
View File

@@ -0,0 +1,470 @@
# INPUT_INFO_ANALYSIS
Анализ материалов из папки `input_info` для приведения проекта в соответствие с официальной постановкой задачи OZON Tech Track 3.
## 1. Что найдено в input_info
| Путь файла | Тип | Содержит | Важность | Как использовать |
|------------|-----|----------|----------|------------------|
| `doc-1783009063.pdf` | PDF | Перечень допустимого ПО | Средняя | Подтверждение стека (React, Docker, open-source инструменты) |
| `doc-1783009942.pdf` | PDF | Схема рабочей зоны с размерами | Высокая | Размеры зон A/B/C/D, ролл-кейджей; добавить в документацию |
| `doc-1783011400.pdf` | PDF | Критерии оценки Track 3 | **Критическая** | Матрица баллов, детальные требования к презентации/УГТ/корректности |
| `extracted/Постановка_Задача_3_сжато_2.pdf` | PDF | Полная постановка задачи (17 стр) | **Критическая** | Официальные параметры классификации, правила, глоссарий, требования к сдаче |
| `doc-1782987706.zip` → `Step/*.stp` | STEP | 11 3D-моделей товаров | Высокая | Тестовый набор для проверки классификации |
| `doc-1782987733.zip` → `Stl/*.stl` | STL | 11 3D-моделей товаров (дубликат) | Средняя | Альтернативный формат моделей для симуляций |
| `ozone-tech_owl_prime_170-main.zip` | ZIP | Пустой README.md | Низкая | Не содержит полезных материалов |
**Тестовый набор товаров (STEP/STL):**
1. Бутылка
2. Короб 300×200×200
3. Короб 400×400×300
4. ЛанчБокс
5. Мешок
6. Моющее средство
7. Пуфик
8. Ручка
9. Тарелка
10. Цилиндр
11. Шлем
## 2. Ключевые требования из input_info
### 2.1. Параметры классификации (КРИТИЧЕСКИЕ ИСПРАВЛЕНИЯ)
Из `Постановка_Задача_3_сжато_2.pdf`:
#### Минимальные габариты:
- **Официально:** 10×10×**2 мм**
- **В текущем коде:** 10×10×**10 мм** ❌
#### Максимальные габариты:
- **Официально:** 450×320×320 мм ✅
- **В текущем коде:** 450×320×320 мм ✅
#### Порог круглости:
- **Официально:** K = r_in / r_out ≥ **0.7**
- **В текущем коде:** ≥ **0.8** ❌
#### Скорость конвейера:
- **Официально:** 1.0 м/с ✅
- **В текущем коде:** 1.0 м/с ✅
### 2.2. Правила классификации
**Категория B "Подходит для сортировки":**
- Габариты: 10×10×**2** мм ≤ размеры ≤ 450×320×320 мм
- НЕТ круга в сечении (K < 0.7)
**Категория C "Не подходит по габаритам":**
- Размеры < 10×10×**2** мм ИЛИ > 450×320×320 мм
- **C имеет приоритет над D** (проверка габаритов идёт первой)
**Категория D "Не подходит без доупаковки":**
- Габариты проходят
- Есть круг в сечении (K ≥ 0.7)
**Порядок проверки:**
1. Сначала габариты → если не прошли, категория **C**
2. Затем форма → если круг, категория **D**
3. Иначе категория **B**
### 2.3. Схема участка (из doc-1783009942.pdf)
- **Рабочая зона:** 6000×10000 мм (фиксированная)
- **A (подача):** конвейерная линия 500×700 мм (фикс)
- **B (основной сортировщик):** конвейерная линия 500×700 мм (фикс относительно A)
- **C (негабарит):** ролл-кейдж 1200×800×800 мм (свободное размещение в рабочей зоне)
- **D (неправильная форма):** ролл-кейдж 1200×800×800 мм (свободное размещение в рабочей зоне)
### 2.4. Критерии оценки (из doc-1783011400.pdf)
**Раздел 1. Презентация (0-10 баллов)**
- 0-5: Ясность материалов
- 0-5: Выступление и ответы на вопросы
**Раздел 2. УГТ (0-20 баллов)**
- Матрица 4×4: ось CV (1-4) × ось исполнительной части (1-4)
**Раздел 3. Корректность определения (0-20 баллов)**
- 0-10: Корректность на тестовом наборе
- 0-5: Полнота правил классификации
- 0-5: Устойчивость в пограничных случаях
**Раздел 4. Исполнительная часть (0-30 баллов)**
- 0-10: Корректность физической маршрутизации
- 0-10: Качество манипуляции
- 0-5: Разная геометрия объектов
- 0-5: Безопасность эксплуатации
**Раздел 5. Производительность (0-20 баллов)**
- 0-10: Cycle time и производительность
- 0-5: Синхронизация по времени
- 0-5: Устойчивость к нештатным ситуациям
**Раздел 6. Связность (0-15 баллов)**
- 0-10: Связность CV и исполнительной части
- 0-5: Инженерная реалистичность
**Раздел 7. Отчетность (0-15 баллов)**
- 0-5: Полнота и качество отчета
- 0-5: Воспроизводимость и удобство проверки
- 0-5: Полнота комплекта сдачи
**Итого:** 130 баллов
### 2.5. Требования к сдаче (из Постановки задачи)
**Обязательный состав:**
- Описание подхода к классификации ✅
- Исходный код алгоритмической части ✅
- Проектные материалы по исполнительной части ✅
- Цифровая модель / симуляция / расчётное обоснование ✅ (3D digital twin)
- Описание связи CV → исполнительная часть ✅
- Итоговый отчет команды ✅
- Видеодемонстрация работы ⏳ (TODO)
**Формат презентации:**
- Длительность: не более **7 минут**
- Формат: живая демонстрация / видео / комбинация
**Рекомендуемая структура презентации:**
1. О команде
2. Постановка задачи и подход
3. Логика классификации
4. Схема маршрутизации A/B/C/D
5. Исполнительная часть и автоматическая перекладка
6. Подтверждение: метрики, симуляция, расчёты, цифровой прототип
7. Используемые инструменты и выбор
8. Ограничения и развитие
## 3. Что уже реализовано
✅ **Архитектура:** React + Vite + TypeScript + Three.js
✅ **Классификация:** Чистая функция `classifyItem` с габаритами и roundness
✅ **State machine:** IDLE → DETECTING → CLASSIFYING → ROUTE_TO_* → RETURN_HOME
✅ **Исполнительная часть:** Stop-gate, pusher C, pusher D, физическая маршрутизация
✅ **3D Digital Twin:** React Three Fiber, labels A/B/C/D, route beams, roll-cages
✅ **2D Fallback:** SVG для mobile и WebGL unavailable
✅ **Сценарии:** normal_flow, oversized_item, round_object, c_priority, boundary_dimensions, close_items, low_confidence, jam, emergency_stop
✅ **Criteria Cards:** Покрытие критериев OZON с привязкой к сценариям
✅ **Engineering Details:** Sensors, PID, Timeline, Event Log, 3D capability check
✅ **Документация:** README, ARCHITECTURE, DEMO_SCRIPT, SCENARIOS, JURY_QA, SUBMISSION_CHECKLIST, UI_UX_REDESIGN_AUDIT, THREE_D_FEASIBILITY
✅ **Тесты:** 16/16 passed (classifier, scenarios, demo steps, criteria)
✅ **Docker:** compose project `owl`, nginx, domain checks OK
✅ **C-priority:** Габариты проверяются первыми, oversized + round → C
## 4. Что нужно добавить/исправить
### 4.1. КРИТИЧЕСКИЕ исправления параметров
❌ **`src/domain/classifier.ts`:**
```typescript
// БЫЛО:
min: { width: 10, depth: 10, height: 10 },
roundnessThreshold: 0.8,
// ДОЛЖНО БЫТЬ:
min: { width: 10, depth: 10, height: 2 },
roundnessThreshold: 0.7,
```
❌ **`README.md`:**
- Строка 153: "min: width >= 10 мм, depth >= 10 мм, height >= 10 мм" → **height >= 2 мм**
- Строка 155: "roundness threshold: 0.8" → **0.7**
- Строка 132: "roundness >= 0.8" → **>= 0.7**
❌ **`src/data/scenarios.ts`:**
- Строка 26: "roundness >= 0.8" → **>= 0.7**
❌ **`docs/JURY_QA.md`:**
- Строка 45: "10×10×10 mm" → **10×10×2 mm**
- Строка 45: "threshold 0.8" → **threshold 0.7**
❌ **`docs/SUBMISSION_CHECKLIST.md`:**
- Строка 21: "10×10×10 mm" → **10×10×2 mm**
### 4.2. Точечные UX улучшения
⚠️ **Hero Section:**
- Добавить крупный proof-line: `Detection → Classification → ROUTE_TO_* → Actuator → B/C/D`
- Добавить бейджи параметров: `Конвейер 1 м/с`, `Min 10×10×2 мм`, `Max 450×320×320 мм`, `K ≥ 0.7 → D`, `C priority`
⚠️ **Product Demo Section:**
- Сделать крупнее блок текущего решения: **Category / Command / Target / Why**
- Для C-priority явно показать: "dimensions failed, so C has priority even though K = 0.93"
⚠️ **C-priority explanation:**
- Добавить заметную карточку/блок с объяснением приоритета C над D
⚠️ **Mobile fallback:**
- Добавить текст объяснения: "3D Digital Twin доступен на desktop. На узком экране включена 2D-схема с той же логикой."
⚠️ **Engineering Details:**
- Добавить пояснение про physics engine: "Physics engine не включён в production-сцену намеренно: для защиты важна воспроизводимая маршрутизация B/C/D."
### 4.3. Документация
⚠️ **README.md:**
- Добавить раздел "input_info" с описанием использованных материалов
- Добавить упоминание тестового набора товаров (11 STEP/STL моделей)
⚠️ **DEMO_SCRIPT.md:**
- Добавить финальный 7-минутный тайминг:
- 0:00–0:20 что это
- 0:20–0:45 полный контур
- 0:45–1:30 B
- 1:30–2:15 C
- 2:15–3:00 D
- 3:00–3:45 C-priority
- 3:45–4:30 low confidence/fault
- 4:30–5:30 Engineering Details
- 5:30–6:30 критерии и метрики
- 6:30–7:00 ограничения и развитие
⚠️ **JURY_QA.md:**
- Добавить вопрос про physics engine (уже есть, но дополнить)
- Добавить вопрос про тестовый набор STEP/STL моделей
- Обновить параметры 10×10×2 и 0.7
⚠️ **SUBMISSION_CHECKLIST.md:**
- Обновить параметры
- Добавить пункт про input_info analysis
⚠️ **Новый файл: docs/INPUT_INFO_ANALYSIS.md** ✅ (этот документ)
### 4.4. Тесты
⚠️ **Обновить тесты под новые параметры:**
- classifier.test.ts: проверки min height 2 мм, roundness 0.7
- scenarios.test.ts: обновить ожидаемые результаты если изменились
### 4.5. 3D Scene labels
⚠️ **Проверить метки в 3D:**
- A Input
- Накопитель / Accumulator
- CV Camera
- Stop-gate
- Pusher C
- Pusher D
- B Main sorter
- C Dimensions reject
- D Repack
Убедиться, что labels крупные и понятные.
## 5. Что использовать в UI
### Формулировки для Hero:
**Заголовок:**
> Интеллектуальная система предварительной сортировки товаров
**Подзаголовок:**
> 3D-симуляция ПАК показывает полный цикл: товар поступает из A, определяется CV-модулем, классифицируется в B/C/D и физически маршрутизируется исполнительной частью.
**Proof-line:**
> Detection → Classification → ROUTE_TO_* → Actuator → B/C/D
**Бейджи параметров:**
- Конвейер 1 м/с
- Min 10×10×2 мм
- Max 450×320×320 мм
- K ≥ 0.7 → D
- C priority
### Формулировки для Product Demo:
**Current decision summary (крупно):**
```
Category: B / C / D
Command: ROUTE_TO_B / ROUTE_TO_C / ROUTE_TO_D
Target: Zone B / Zone C / Zone D
Why: [1 короткая строка]
```
**Примеры Why:**
- B: "dimensions pass and round section is not detected"
- C: "dimensions failed (oversized)"
- D: "dimensions pass, but K = 0.92 ≥ 0.7"
- C-priority: "dimensions failed, so C has priority even though K = 0.93"
### Формулировки для C-priority explanation:
**Заголовок:**
> Почему C имеет приоритет?
**Текст:**
> Если товар одновременно негабаритный и имеет круг в сечении, он направляется в C. Сначала проверяются габариты, и только если они проходят — форма. Это предотвращает попадание негабаритных объектов в основной сортировщик.
### Формулировки для mobile fallback:
> 3D Digital Twin доступен на desktop. На узком экране включена 2D-схема с той же логикой классификации и маршрутизации.
### Формулировки для Engineering Details (physics engine):
> В демо используется управляемая 3D state-machine simulation. Physics engine не включён в production-сцену намеренно: для защиты важна воспроизводимая маршрутизация B/C/D. Архитектура допускает подключение physics engine позднее.
## 6. Что использовать в документации
### README.md:
**Новый раздел после "Стек":**
```markdown
## input_info
Проект разработан в соответствии с официальной постановкой задачи OZON Tech Track 3.
**Использованные материалы:**
- `Постановка_Задача_3_сжато_2.pdf` — полная постановка задачи (правила классификации, схема участка, критерии оценки)
- `doc-1783009942.pdf` — схема рабочей зоны с размерами A/B/C/D
- `doc-1783011400.pdf` — критерии оценки Track 3 (матрица баллов)
- `doc-1782987706.zip` → STEP модели тестовых товаров (11 шт)
- `doc-1782987733.zip` → STL модели тестовых товаров (11 шт)
**Тестовый набор товаров:**
Цилиндр, Шлем, Бутылка, Мешок, Тарелка, Короб 400×400×300, ЛанчБокс, Короб 300×200×200, Пуфик, Ручка, Моющее средство.
**Параметры классификации (согласно постановке):**
- Min dimensions: **10×10×2 мм**
- Max dimensions: 450×320×320 мм
- Roundness threshold: K ≥ **0.7**
- Conveyor speed: 1.00 м/с
- C-priority: габариты проверяются первыми
Подробный анализ: `docs/INPUT_INFO_ANALYSIS.md`
```
### DEMO_SCRIPT.md:
**Добавить секцию "7-Minute Structure":**
```markdown
## 7-Minute Structure
Рекомендуемый тайминг для защиты (максимум 7 минут):
- **0:00–0:20** Что это за система? ПАК предварительной сортировки, полный цикл A → CV → B/C/D.
- **0:20–0:45** Полный контур: Detection → Classification → Command → Actuator → Route.
- **0:45–1:30** Категория B: габариты проходят, нет круга, зелёный маршрут в основной сортировщик.
- **1:30–2:15** Категория C: негабаритный товар, оранжевый маршрут в roll-cage C.
- **2:15–3:00** Категория D: габариты проходят, но круг в сечении (K ≥ 0.7), фиолетовый маршрут в roll-cage D.
- **3:00–3:45** C-priority: негабаритный + круглый → всё равно C (приоритет габаритов).
- **3:45–4:30** Low confidence и fault: rule-based fallback, FAULT состояние, EMERGENCY_STOP.
- **4:30–5:30** Engineering Details: timeline, PID, sensors, event log, 3D capability check.
- **5:30–6:30** Критерии OZON и метрики: cycle time, устойчивость, воспроизводимость.
- **6:30–7:00** Ограничения MVP и развитие: real CV, physics engine, WebSocket телеметрия.
```
### JURY_QA.md:
**Обновить вопрос 11:**
```markdown
## 11. How Are Dimensions And Circular Section Handled?
Dimensions are checked first against min/max: **10×10×2 mm** to 450×320×320 mm. If they pass, roundness K = r_in / r_out is checked against threshold **0.7**. Conveyor target speed is 1.00 m/s.
```
**Добавить новый вопрос 22:**
```markdown
## 22. Where Are The Test Object Models From input_info?
The official test set includes 11 STEP/STL models from input_info: Cylinder, Helmet, Bottle, Bag, Plate, Box 400×400×300, Lunchbox, Box 300×200×200, Pouf, Pen, Detergent. These models can be used to validate classification correctness on realistic geometries.
```
## 7. Риски
### 7.1. Изменение параметров может сломать тесты
✅ **Митигация:** Сначала обновить `classifier.ts`, затем запустить тесты, исправить ожидаемые результаты где нужно.
### 7.2. Изменение min height с 10 на 2 мм может изменить категории некоторых товаров
✅ **Митигация:** Проверить все товары в `items.ts`:
- SKU-009 (Pen 9×13×148): width 9 < 10, всё равно C ✅
- Остальные товары имеют height > 10 мм, изменение не влияет ✅
### 7.3. Изменение roundness threshold с 0.8 на 0.7 может изменить категории
✅ **Митигация:** Проверить все товары:
- SKU-006 (Plate, roundness 0.95): было D, останется D ✅
- SKU-007 (Bottle, roundness 0.92): было D, останется D ✅
- SKU-008 (Cylinder, roundness 0.88): было D, останется D ✅
- SKU-005 (Pouf, roundness 0.74): было C (oversized), останется C ✅
- Нет товаров с roundness между 0.7 и 0.8, которые меняют категорию ✅
### 7.4. Нет видеодемонстрации
⚠️ **Риск:** Требование к сдаче включает видеодемонстрацию работы решения.
✅ **Митигация:** Указать в SUBMISSION_CHECKLIST и JURY_QA, что live demo на сайте заменяет видео, но при необходимости можно записать screen capture 7-минутного прохода.
### 7.5. Нет реального ML / CV
⚠️ **Риск:** Жюри может спросить про настоящее машинное зрение.
✅ **Митигация:** Уже указано в JURY_QA.md: "The MVP uses pseudo-CV: bbox, dimensions, confidence and latency are derived from mock items. The architecture keeps CV output separate from classification, so a real CV service can replace it later."
## 8. Definition of Done
Проект готов к защите, когда выполнены все пункты:
### 8.1. Параметры классификации
- [ ] `src/domain/classifier.ts`: min height = 2 мм, roundness threshold = 0.7
- [ ] `README.md`: обновлены параметры
- [ ] `src/data/scenarios.ts`: обновлено описание roundness
- [ ] `docs/JURY_QA.md`: обновлены параметры
- [ ] `docs/SUBMISSION_CHECKLIST.md`: обновлены параметры
### 8.2. UX улучшения
- [ ] Hero: добавлен proof-line и бейджи параметров
- [ ] Product Demo: крупный блок Category / Command / Target / Why
- [ ] C-priority: отдельная карточка/блок объяснения
- [ ] Mobile fallback: текст объяснения
- [ ] Engineering Details: пояснение про physics engine
### 8.3. Документация
- [ ] `docs/INPUT_INFO_ANALYSIS.md`: создан ✅
- [ ] `README.md`: добавлен раздел input_info
- [ ] `DEMO_SCRIPT.md`: добавлен 7-минутный тайминг
- [ ] `JURY_QA.md`: обновлены ответы, добавлен вопрос про тестовые модели
- [ ] `SUBMISSION_CHECKLIST.md`: обновлён
### 8.4. Тесты
- [ ] `npm run test` проходит
- [ ] Все 16+ тестов зелёные
### 8.5. Build & Deploy
- [ ] `npm run build` успешно
- [ ] Docker project `owl` перезапущен
- [ ] `https://arhipovdan.ru/` открывается
- [ ] `https://www.arhipovdan.ru/` открывается
- [ ] `https://ai-shorts.ru/` не затронут
### 8.6. Visual QA
- [ ] Desktop 1920×1080: Hero понятен, proof-line виден, бейджи читаемы
- [ ] Laptop 1440×900: Category/Command/Target крупные
- [ ] Mobile 390×844: fallback объяснён, нет horizontal scroll
- [ ] Сценарии: B / C / D / C-priority / low confidence / fault / emergency работают
- [ ] Console: no React errors, no WebGL errors
### 8.7. Git
- [ ] `git status` показывает только изменённые файлы (нет мусора)
- [ ] `git diff` проверен
- [ ] Команды для commit/push подготовлены (но НЕ выполнены)
---
**Дата создания:** 2026-07-04
**Автор:** Claude Sonnet 4.5
**Цель:** Привести проект в полное соответствие с официальной постановкой задачи OZON Tech Track 3 перед финальной защитой.

View File

@@ -42,7 +42,7 @@ The proof card shows dimensions, roundness and reason. Tests cover key boundary
## 11. How Are Dimensions And Circular Section Handled?
Dimensions are checked first against min/max: 10×10×10 mm to 450×320×320 mm. If they pass, roundness K = r_in / r_out is checked against threshold 0.8. Conveyor target speed is 1.00 m/s.
Dimensions are checked first against min/max: 10×10×2 mm to 450×320×320 mm. If they pass, roundness K = r_in / r_out is checked against threshold 0.7. Conveyor target speed is 1.00 m/s.
## 12. Why Does C Have Priority Over D?
@@ -91,3 +91,7 @@ document.documentElement.scrollWidth <= document.documentElement.clientWidth
## 21. Where is the WebGL / FPS check?
Open Engineering Details → **3D capability check**.
## 22. Where Are The Test Object Models From input_info?
The official test set includes 11 STEP/STL models from input_info: Cylinder, Helmet, Bottle, Bag, Plate, Box 400×400×300, Lunchbox, Box 300×200×200, Pouf, Pen, Detergent. These models can be used to validate classification correctness on realistic geometries. The demo uses mock items derived from these dimensions and shapes.

View File

@@ -18,7 +18,7 @@ Before final submission:
- [ ] Jam / emergency stop show red fault state.
- [ ] Physics engine is NOT required for the demo (state-machine motion).
- [ ] Engineering Details includes 3D capability check (WebGL / FPS).
- [ ] Min dimensions are 10×10×10 mm; conveyor target is 1.00 m/s.
- [ ] Min dimensions are 10×10×2 mm; roundness threshold is 0.7; conveyor target is 1.00 m/s.
- [ ] Storyline Stepper updates with machine state.
- [ ] Scenario cards open cases with **Показать**.
- [ ] Criteria cards show OZON coverage and linked scenarios.
@@ -27,7 +27,7 @@ Before final submission:
- [ ] NO horizontal scroll on body / `#root` / product page.
- [ ] Mobile: one column, buttons ≥ 44px, scene scales.
- [ ] Scenarios checked: normal_flow, oversized_item, round_object, c_priority, boundary_dimensions, close_items, low_confidence, jam, emergency_stop.
- [ ] Docs present: README, ARCHITECTURE, DEMO_SCRIPT, SCENARIOS, JURY_QA, UI_UX_REDESIGN_AUDIT, THREE_D_FEASIBILITY, SUBMISSION_CHECKLIST.
- [ ] Docs present: README, ARCHITECTURE, DEMO_SCRIPT, SCENARIOS, JURY_QA, UI_UX_REDESIGN_AUDIT, THREE_D_FEASIBILITY, SUBMISSION_CHECKLIST, INPUT_INFO_ANALYSIS.
- [ ] Cursor rules present in `.cursor/rules/` (including 3D / physics / WebGL rules).
- [ ] Branch ready for manual push to `origin/dan_branch`.
- [ ] Nginx / SSL / neighboring projects were not modified.

View File

@@ -4,6 +4,7 @@ import HeroSection from './components/HeroSection';
import ProductDemoSection from './components/ProductDemoSection';
import StorylineStepper from './components/StorylineStepper';
import ScenarioCards from './components/ScenarioCards';
import CPriorityExplanation from './components/CPriorityExplanation';
import CriteriaCards from './components/CriteriaCards';
import EngineeringDetails, { type EngineeringDetailsHandle } from './components/EngineeringDetails';
import { DEMO_STEPS } from './data/demoSteps';
@@ -79,6 +80,10 @@ export default function App() {
scrollToId('scenarios');
};
const handleShowCPriority = () => {
handleScenarioChange('c_priority');
};
return (
<div className="product-page">
<Header
@@ -113,6 +118,8 @@ export default function App() {
onScenarioChange={handleScenarioChange}
/>
<CPriorityExplanation onShowCPriority={handleShowCPriority} />
<CriteriaCards onLinkedScenario={handleScenarioChange} />
<EngineeringDetails

View File

@@ -0,0 +1,26 @@
interface CPriorityExplanationProps {
onShowCPriority: () => void;
}
export default function CPriorityExplanation({ onShowCPriority }: CPriorityExplanationProps) {
return (
<section className="c-priority-section" aria-labelledby="c-priority-title">
<div className="c-priority-card">
<div className="c-priority-icon" aria-hidden="true">
C
</div>
<div className="c-priority-content">
<h3 id="c-priority-title">Почему C имеет приоритет?</h3>
<p>
Если товар одновременно негабаритный и имеет круг в сечении, он направляется в C.
Сначала проверяются габариты, и только если они проходят — форма.
Это предотвращает попадание негабаритных объектов в основной сортировщик.
</p>
<button type="button" className="btn-primary" onClick={onShowCPriority}>
Показать C-priority
</button>
</div>
</div>
</section>
);
}

View File

@@ -29,7 +29,7 @@ const PRODUCT_CRITERIA: CriteriaCard[] = [
{
id: 'round-section',
title: 'Круг в сечении',
evidence: 'Roundness ≥ 0.8 направляет товар в зону D.',
evidence: 'Roundness ≥ 0.7 направляет товар в зону D.',
status: 'covered',
linkedScenario: 'round_object',
linkedLabel: 'Круглый объект',

View File

@@ -40,6 +40,33 @@ export default function CurrentProofCard({ simulation }: { simulation: Simulatio
<h3>{item?.name}</h3>
</div>
<div className="proof-summary">
<div className="summary-row">
<span className="summary-label">Category:</span>
<strong className={`category-${result?.category ?? 'default'}`}>{result?.category ?? '—'}</strong>
</div>
<div className="summary-row">
<span className="summary-label">Command:</span>
<strong>{command}</strong>
</div>
<div className="summary-row">
<span className="summary-label">Target:</span>
<strong>{result?.category ? `Zone ${result.category}` : '—'}</strong>
</div>
<div className="summary-row">
<span className="summary-label">Why:</span>
<em>
{isCPriority
? `dimensions failed, so C has priority even though K = ${item?.roundness.toFixed(2)}`
: result?.dimensionsPass === false
? 'dimensions failed (oversized or undersized)'
: result?.roundnessPass === false
? `dimensions pass, but K = ${item?.roundness.toFixed(2)} ≥ 0.7`
: 'dimensions pass and round section is not detected'}
</em>
</div>
</div>
<div className="proof-grid">
<div className="proof-item">
<span className="proof-label">Dimensions</span>
@@ -55,7 +82,7 @@ export default function CurrentProofCard({ simulation }: { simulation: Simulatio
<strong className={result?.roundnessPass === false && result?.dimensionsPass ? 'fail-text' : 'pass-text'}>
{item?.roundness.toFixed(2)}
</strong>
<em>{result?.roundnessPass ? 'PASS' : 'DETECTED (≥0.8)'}</em>
<em>{result?.roundnessPass ? 'PASS' : 'DETECTED (≥0.7)'}</em>
</div>
<div className="proof-item">
<span className="proof-label">Category</span>

View File

@@ -14,19 +14,18 @@ export default function HeroSection({
<div className="hero-content">
<p className="hero-eyebrow">OZON Tech · Product Demo</p>
<h1 id="hero-title" className="hero-title">
Интеллектуальная система сортировки товаров
Интеллектуальная система предварительной сортировки товаров
</h1>
<p className="hero-subtitle">
Симуляция показывает полный цикл: обнаружение товара, классификация по правилам,
управляющая команда и маршрутизация в зоны B/C/D.
3D-симуляция ПАК показывает полный цикл: товар поступает из A, определяется CV-модулем, классифицируется в B/C/D и физически маршрутизируется исполнительной частью.
</p>
<div className="hero-badges" aria-label="Ключевые возможности">
<span className="hero-badge">Computer Vision</span>
<span className="hero-badge">Rule-based classification</span>
<span className="hero-badge">Actuator routing</span>
<span className="hero-badge">Cycle time</span>
<span className="hero-badge">Fault handling</span>
<div className="hero-badges" aria-label="Параметры системы">
<span className="hero-badge">Конвейер 1 м/с</span>
<span className="hero-badge">Min 10×10×2 мм</span>
<span className="hero-badge">Max 450×320×320 мм</span>
<span className="hero-badge">K ≥ 0.7 → D</span>
<span className="hero-badge">C priority</span>
</div>
<div className="hero-actions">
@@ -65,7 +64,7 @@ export default function HeroSection({
</div>
</div>
<p className="hero-chain-caption">
Результат демо: категория B/C/D, команда ROUTE_TO_* и целевая зона
Detection → Classification → ROUTE_TO_* → Actuator → B/C/D
</p>
</div>
</section>

View File

@@ -11,6 +11,7 @@ import RouteArrows3D from './RouteArrows3D';
import SceneLabels3D from './SceneLabels3D';
import { PHYSICS_ENGINE_ENABLED } from './itemMotion';
import { NOMINAL_CONVEYOR_SPEED_MPS } from '../../domain/simulation';
import { DIMENSION_LIMITS } from '../../domain/classifier';
export interface SorterDigitalTwinProps {
simulation: SimulationState;
@@ -142,7 +143,9 @@ export default function SorterDigitalTwin({
{category ? <span className={`twin-chip category-${category}`}>Zone {category}</span> : null}
<span className="twin-chip">{command}</span>
<span className="twin-chip">Conveyor {NOMINAL_CONVEYOR_SPEED_MPS.toFixed(2)} m/s</span>
<span className="twin-chip">Min 10×10×10 mm</span>
<span className="twin-chip">
Min {DIMENSION_LIMITS.min.width}×{DIMENSION_LIMITS.min.depth}×{DIMENSION_LIMITS.min.height} mm
</span>
{showFps ? <span className="twin-chip">FPS ~{fps}</span> : null}
<span className="twin-chip muted-chip">
Motion: {PHYSICS_ENGINE_ENABLED ? 'physics' : 'state-machine'}

View File

@@ -43,7 +43,7 @@ export const DEMO_STEPS: DemoStep[] = [
scenarioId: 'round_object',
preferredAction: 'step',
focusArea: 'scene',
explanation: 'Roundness >= 0.8 after valid dimensions sends the item to D for repack/shape issue handling.',
explanation: 'Roundness >= 0.7 after valid dimensions sends the item to D for repack/shape issue handling.',
whatToWatch: 'Roundness FAIL for B, category D and the upper route/pusher D command.',
juryValue: 'Shows how the circle-section rule becomes a physical route.',
relatedCriteria: ['classification-rules', 'geometry-variety', 'physical-routing'],

View File

@@ -23,7 +23,7 @@ export const SCENARIOS: Scenario[] = [
{
id: 'round_object',
name: 'Round object',
description: 'Габариты проходят, но roundness >= 0.8, маршрут в D.',
description: 'Габариты проходят, но roundness >= 0.7, маршрут в D.',
goal: 'Показать проверку круглого сечения после габаритов.',
expectedCategorySummary: 'D for every item',
demonstrates: 'Rule-based shape issue routing без реального ML на MVP-этапе.',

View File

@@ -6,10 +6,10 @@ import type { Category, Item } from './types';
const VALID_CATEGORIES: Category[] = ['B', 'C', 'D'];
describe('classifyItem', () => {
it('uses min dimensions 10×10×10 mm', () => {
expect(DIMENSION_LIMITS.min).toEqual({ width: 10, depth: 10, height: 10 });
it('uses min dimensions 10×10×2 mm', () => {
expect(DIMENSION_LIMITS.min).toEqual({ width: 10, depth: 10, height: 2 });
expect(DIMENSION_LIMITS.max).toEqual({ width: 450, depth: 320, height: 320 });
expect(DIMENSION_LIMITS.roundnessThreshold).toBe(0.8);
expect(DIMENSION_LIMITS.roundnessThreshold).toBe(0.7);
});
it('routes normal box to B', () => {
@@ -40,11 +40,11 @@ describe('classifyItem', () => {
expect(classifyItem(getItem('SKU-010')).category).toBe('B');
});
it('rejects height below 10 mm as C', () => {
it('rejects height below 2 mm as C', () => {
const item: Item = {
...getItem('SKU-001'),
id: 'TEST-LOW-HEIGHT',
dimensionsMm: { width: 100, depth: 100, height: 9 },
dimensionsMm: { width: 100, depth: 100, height: 1 },
};
expect(classifyItem(item).category).toBe('C');
expect(classifyItem(item).dimensionsPass).toBe(false);

View File

@@ -16,9 +16,9 @@ export const CATEGORY_DEFINITIONS: Record<Category, CategoryDefinition> = {
};
export const DIMENSION_LIMITS = {
min: { width: 10, depth: 10, height: 10 },
min: { width: 10, depth: 10, height: 2 },
max: { width: 450, depth: 320, height: 320 },
roundnessThreshold: 0.8,
roundnessThreshold: 0.7,
};
export function classifyItem(item: Item): ClassificationResult {

View File

@@ -690,6 +690,46 @@ button:disabled {
font-size: 1.25rem;
}
.proof-summary {
display: flex;
flex-direction: column;
gap: 10px;
padding: 16px;
border: 2px solid var(--cyan);
border-radius: 12px;
background: rgba(56, 189, 248, 0.06);
}
.summary-row {
display: flex;
align-items: baseline;
gap: 8px;
flex-wrap: wrap;
}
.summary-label {
color: var(--cyan);
font-size: 14px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
min-width: 88px;
}
.summary-row strong {
font-size: 18px;
font-weight: 800;
}
.summary-row em {
flex: 1;
min-width: 200px;
color: var(--muted);
font-size: 14px;
font-style: normal;
line-height: 1.4;
}
.proof-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
@@ -976,6 +1016,71 @@ button:disabled {
font-weight: 700;
}
/* ---------- C-priority explanation ---------- */
.c-priority-section {
margin: clamp(40px, 6vw, 72px) 0;
}
.c-priority-card {
display: flex;
gap: 20px;
align-items: center;
padding: clamp(20px, 4vw, 32px);
border: 2px solid var(--orange);
border-radius: 20px;
background: linear-gradient(135deg, rgba(245, 158, 11, 0.08) 0%, rgba(245, 158, 11, 0.02) 100%);
}
.c-priority-icon {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 72px;
height: 72px;
border-radius: 16px;
background: var(--orange);
color: #041018;
font-size: 36px;
font-weight: 900;
}
.c-priority-content {
display: flex;
flex-direction: column;
gap: 12px;
flex: 1;
}
.c-priority-content h3 {
font-size: 1.5rem;
color: var(--text);
}
.c-priority-content p {
color: var(--muted);
font-size: 15px;
line-height: 1.5;
}
.c-priority-content .btn-primary {
align-self: flex-start;
margin-top: 4px;
}
@media (max-width: 640px) {
.c-priority-card {
flex-direction: column;
text-align: center;
}
.c-priority-content .btn-primary {
align-self: stretch;
width: 100%;
}
}
/* ---------- Engineering details ---------- */
.engineering-toggle {