
- Исправлен missing dependency в useSupplyCart.ts - Исправлен missing dependency в useWildberriesProducts.ts - Добавлен useCallback для getProductTotalWithRecipe для стабильности - Оптимизированы зависимости в useMemo и useCallback хуках - Обновлена система правил для разделенных файлов rules-complete1/2 - Созда��а система проактивного мониторинга контекста - Добавлен детальный план безопасного рефакторинга больших компонентов 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
67 KiB
rules-complete2
❌ ЗАПРЕЩЕНО РЕДАКТИРОВАТЬ БЕЗ ЯВНОГО РАЗРЕШЕНИЯ ПОЛЬЗОВАТЕЛЯ!
13. 🤝 СИСТЕМА ПАРТНЕРСТВА И КОНТРАГЕНТОВ
13.1 Основы системы партнерства
ПРИНЦИП РАБОТЫ:
- Все типы кабинетов могут создавать партнерские отношения
- Партнерство реализовано через таблицы
Counterparty
иCounterpartyRequest
- Двустороннее партнерство: каждая организация видит другую в разделе "Партнеры"
ТИПЫ ОРГАНИЗАЦИЙ-ПАРТНЕРОВ:
WHOLESALE
- Поставщики товаров и расходниковFULFILLMENT
- Фулфилмент-центрыLOGIST
- Логистические компанииSELLER
- Селлеры (торговые организации)
13.2 Способы создания партнерства
СПОСОБ 1: Через заказ в маркете (автоматическое партнерство)
WORKFLOW:
- Поставщик создает товар → товар попадает в глобальный маркет
- Селлер/Фулфилмент находит товар в маркете
- Создает заказ (
SupplyOrder
) → статусPENDING
- Поставщик получает уведомление в разделе "Заявки"
- Поставщик одобряет заявку → статус
SUPPLIER_APPROVED
- Автоматически создается двустороннее партнерство:
- Запись в
Counterparty
для заказчика (organizationId
→counterpartyId
) - Обратная запись в
Counterparty
для поставщика
- Запись в
- Обе организации видят друг друга в разделе "Партнеры"
СПОСОБ 2: Через раздел "Партнеры" (заявочная система)
WORKFLOW:
- Любая организация идет в раздел "Партнеры"
- Использует поиск для нахождения нужной организации
- Отправляет заявку на партнерство → создается
CounterpartyRequest
:senderId
- отправитель заявкиreceiverId
- получатель заявкиstatus: PENDING
message
- опциональное сообщение
- Получатель видит заявку в разделе "Партнеры" → "Входящие заявки"
- Получатель принимает заявку → статус меняется на
ACCEPTED
- Автоматически создается двустороннее партнерство (аналогично способу 1)
СТАТУСЫ ЗАЯВОК:
PENDING
- Ожидает рассмотренияACCEPTED
- Принята (партнерство создано)REJECTED
- ОтклоненаCANCELLED
- Отменена отправителем
13.3 Использование партнерства в системе
В форме создания поставки товаров через поставщиков
ПРАВИЛО ОТОБРАЖЕНИЯ ПОСТАВЩИКОВ:
- Показываются только партнеры с типом
WHOLESALE
- Источник: таблица
Counterparty
wherecounterparty.type === "WHOLESALE"
- Фильтрация по
organizationId
текущего пользователя
ЛОГИКА РАБОТЫ:
- Пользователь выбирает поставщика из dropdown партнеров-поставщиков
- Загружается каталог товаров поставщика из
Product
таблицы - Товары фильтруются по
organizationId = поставщик.id
- Пользователь может добавлять товары в корзину и создавать заказ
В других разделах системы
ВЫБОР ФУЛФИЛМЕНТ-ЦЕНТРА:
- Партнеры с типом
FULFILLMENT
- Используется при создании поставок расходников
ВЫБОР ЛОГИСТИКИ:
- Партнеры с типом
LOGIST
- Используется при планировании доставок
МЕССЕНДЖЕР:
- Общение доступно только между партнерами
- Список чатов формируется из таблицы
Counterparty
13.4 Технические правила
СОЗДАНИЕ ЗАПИСЕЙ В COUNTERPARTY:
-- При создании партнерства создаются ДВЕ записи
INSERT INTO counterparties (organizationId, counterpartyId) VALUES (org1_id, org2_id);
INSERT INTO counterparties (organizationId, counterpartyId) VALUES (org2_id, org1_id);
ПРОВЕРКА ПАРТНЕРСТВА:
const isPartner = await prisma.counterparty.findFirst({
where: {
organizationId: currentOrgId,
counterpartyId: targetOrgId,
},
})
ПОЛУЧЕНИЕ ПАРТНЕРОВ ПО ТИПУ:
const wholesalePartners = await prisma.counterparty.findMany({
where: {
organizationId: currentOrgId,
counterparty: {
type: 'WHOLESALE',
},
},
include: {
counterparty: true,
},
})
13.5 Решение распространенных проблем
ПРОБЛЕМА: GraphQL запрос не возвращает данные партнеров
Симптомы:
- В консоли браузера:
All counterparties: 0
,All counterparties data: []
- GraphQL запрос отправляется успешно, но возвращает пустой массив
- В базе данных партнеры существуют
Возможные причины и решения:
-
НЕПРАВИЛЬНОЕ ИМЯ ПОЛЯ В КОДЕ (наиболее частая ошибка):
// ❌ НЕПРАВИЛЬНО const allCounterparties = counterpartiesData?.getMyCounterparties || [] // ✅ ПРАВИЛЬНО const allCounterparties = counterpartiesData?.myCounterparties || []
Объяснение: В GraphQL схеме поле называется
myCounterparties
, а неgetMyCounterparties
-
НЕСООТВЕТСТВИЕ ID ПОЛЬЗОВАТЕЛЯ:
- Проверить что пользователь авторизован под правильным аккаунтом
- Убедиться что
context.user.id
соответствует ожидаемому пользователю
-
ПРОБЛЕМЫ С КЕШИРОВАНИЕМ APOLLO CLIENT:
const { data, loading, error } = useQuery(GET_MY_COUNTERPARTIES, { fetchPolicy: 'network-only', // Обходим кеш errorPolicy: 'all', })
-
ОТСУТСТВИЕ ЛОГИРОВАНИЯ В РЕЗОЛВЕРЕ:
- Добавить console.log в GraphQL резолвер для отладки
- Проверить что резолвер вызывается
Чек-лист для диагностики:
- Проверить правильность имени поля в коде (
myCounterparties
) - Убедиться что пользователь авторизован
- Проверить логи сервера на вызов резолвера
- Добавить отладочное логирование в браузере
- Проверить данные в базе через Prisma Studio
- Использовать
fetchPolicy: 'network-only'
для обхода кеша
13.6 Различие партнерских и реферальных ссылок
⚠️ КРИТИЧЕСКИ ВАЖНО: НЕ ПУТАТЬ два различных типа ссылок в системе!
13.6.1 Партнерские ссылки
НАЗНАЧЕНИЕ: Бизнес-партнерство с автоматическим добавлением в контрагенты
ФОРМАТ URL: ?partner=REFERRAL_CODE
http://localhost:3000/register?partner=SF2X9K4M7P
ЧТО ПРОИСХОДИТ:
- ✅ Начисляется 100 сфер (⚡) реферальная награда
- ✅ Автоматически создается партнерство: взаимное добавление в контрагенты
- ✅ Устанавливается реферальная связь (
referredById
) - ✅ Создаются записи в таблице
Counterparty
(двусторонние) - ✅ Организации видят друг друга в разделе "Партнеры"
ИСПОЛЬЗОВАНИЕ: Когда нужно сразу стать деловыми партнерами и начать работать
13.6.2 Реферальные ссылки
НАЗНАЧЕНИЕ: Маркетинговое привлечение с наградой, БЕЗ автоматического партнерства
ФОРМАТ URL: ?ref=REFERRAL_CODE
http://localhost:3000/register?ref=SF2X9K4M7P
ЧТО ПРОИСХОДИТ:
- ✅ Начисляется 100 сфер (⚡) реферальная награда
- ✅ Устанавливается реферальная связь (
referredById
) - ❌ НЕ создается партнерство: организации НЕ добавляются в контрагенты
- ❌ Организации НЕ видят друг друга в разделе "Партнеры"
ИСПОЛЬЗОВАНИЕ: Маркетинговые кампании, блогеры, инфлюенсеры
13.6.3 Технические различия в коде
В резолверах регистрации:
// Обработка партнерского кода (создает партнерство)
if (partnerCode) {
// 1. Найти организацию-партнера
// 2. Создать реферальную транзакцию
// 3. Установить реферальную связь
// 4. СОЗДАТЬ ВЗАИМНОЕ ПАРТНЕРСТВО ← Ключевое отличие!
}
// Обработка реферального кода (только награда)
if (referralCode) {
// 1. Найти организацию-реферера
// 2. Создать реферальную транзакцию
// 3. Установить реферальную связь
// 4. БЕЗ создания партнерства ← Ключевое отличие!
}
13.6.4 UI различия
В разделе "Партнеры":
Вкладка "Мои партнеры":
- Партнерская ссылка:
?partner=CODE
(автоматическое партнерство) - Заголовок: "Пригласить партнера"
- Описание: "Для прямого делового сотрудничества"
Вкладка "Рефералы":
- Реферальная ссылка:
?ref=CODE
(только маркетинг) - Заголовок: "Реферальная ссылка"
- Описание: "Для маркетинговых кампаний"
13.6.5 Правила именования
В коде ВСЕГДА использовать:
partnerCode
/partner=
→ бизнес-партнерствоreferralCode
/ref=
→ маркетинговое привлечение
В комментариях и документации:
- "Партнерская ссылка" → автоматическое партнерство
- "Реферальная ссылка" → только маркетинг
ЗАПРЕЩЕНО:
- ❌ Называть партнерские ссылки "реферальными"
- ❌ Называть реферальные ссылки "партнерскими"
- ❌ Использовать термины взаимозаменяемо
- ❌ Путать логику обработки в резолверах
13.6.6 Примеры использования
Сценарий 1 - Деловое партнерство:
Фулфилмент-центр хочет пригласить логистическую компанию
→ Использует партнерскую ссылку ?partner=CODE
→ Логисты регистрируются и сразу становятся партнерами
→ Могут сразу работать друг с другом
Сценарий 2 - Маркетинговая кампания:
Организация запускает рекламу в соцсетях
→ Использует реферальную ссылку ?ref=CODE
→ Люди регистрируются, организация получает сферы
→ Партнерство НЕ создается (это маркетинг)
14. 🌐 ИНТЕГРАЦИИ С СИСТЕМОЙ
14.1 Глобальная интеграция
- МАРКЕТ: Товары поставщиков отображаются в глобальном маркете
- СИНХРОНИЗАЦИЯ: Данные склада синхронизируются с модулем аналитики
- УВЕДОМЛЕНИЯ: Единая система через встроенный мессенджер
14.2 Интеграция с маркетплейсами
- WILDBERRIES: Обязательная проверка активности API ключа
- СИНХРОНИЗАЦИЯ: Регулярное обновление данных из внешних источников
- ЛОКАЛЬНЫЕ КОПИИ: Сохранение данных для офлайн работы
14.3 Интеграция с модулем "Услуги"
РАСХОДНИКИ ФУЛФИЛМЕНТА В УСЛУГАХ:
- Расходники фулфилмента - собственность фулфилмента (куплены у поставщиков)
- Фулфилмент создает заявки-поставки для покупки расходников у поставщиков
- Селлеры могут использовать расходники фулфилмента в разделе "Услуги / Расходники"
- Для создания продукта из товара
- Расходники списываются с остатков фулфилмента
- Стоимость включается в стоимость услуги
WORKFLOW ИСПОЛЬЗОВАНИЯ:
- Селлер выбирает услугу "Создание продукта"
- Указывает базовый товар
- Выбирает необходимые расходники фулфилмента
- Фулфилмент обрабатывает заказ и создает продукт
- Расходники списываются, создается готовый продукт
15. 📊 СТАТИСТИКА И АНАЛИТИКА
15.1 Структура статистики по кабинетам
В КАБИНЕТЕ ПОСТАВЩИКА:
- ТОВАРЫ: Общая статистика товаров поставщика
- РАСХОДНИКИ: Материалы и вспомогательные товары (классифицируются при заказе)
В КАБИНЕТЕ ФУЛФИЛМЕНТА:
- ТОВАРЫ: Базовые товары от поставщиков (принятые на склад)
- ПРОДУКТЫ: Отдельный блок готовой продукции
- БРАК: Статистика потерь и списаний
- РАСХОДНИКИ ФУЛФИЛМЕНТА: Операционные материалы фулфилмента
- РАСХОДНИКИ СЕЛЛЕРОВ: Материалы для товаров селлеров
15.2 Ключевые метрики
ОБЩИЕ ПОКАЗАТЕЛИ:
- Общие остатки, заказано, в пути, остаток, продано
- Подсветка предметов с остатками ниже критического уровня
АКТУАЛИЗАЦИЯ ДАННЫХ:
- При изменении количества в карточке данные актуализируются во всей системе
- Статистика обновляется в реальном времени
- Отслеживание изменений для аналитики
16. 📱 ПРАВИЛА UI/UX И ИНТЕРФЕЙСА
16.1 Отзывчивость интерфейса
- ОБЯЗАТЕЛЬНО: Интерфейс должен работать на всех устройствах
- ПРАВИЛО: Адаптивная сетка для карточек товаров
- ФУНКЦИЯ: Оптимизация для мобильных устройств
- ТРЕБОВАНИЕ: Корректное отображение на экранах от 320px до 4K
16.2 Обратная связь пользователю
- ОБЯЗАТЕЛЬНО: Уведомления об успешных/неуспешных операциях
- ПРАВИЛО: Индикаторы загрузки для длительных операций
- ФУНКЦИЯ: Подтверждение критических действий (удаление, деактивация)
- UX: Понятные сообщения об ошибках с предложением решения
16.3 Правила обработки ошибок
- ОБЯЗАТЕЛЬНО: Логирование всех ошибок с детальной информацией
- ПРАВИЛО: Понятные сообщения об ошибках для пользователя
- ФУНКЦИЯ: Автоматическое восстановление после сбоев
- МОНИТОРИНГ: Отслеживание критических ошибок в реальном времени
16.4 Производительность
- ПРАВИЛО: Пагинация для больших списков товаров
- ФУНКЦИЯ: Ленивая загрузка изображений
- ОПТИМИЗАЦИЯ: Кэширование часто запрашиваемых данных
- ПРОИЗВОДИТЕЛЬНОСТЬ: Время загрузки страницы не более 3 секунд
17. ⚠️ КРИТИЧЕСКИЕ ЗАПРЕТЫ
17.1 НИКОГДА НЕ ДЕЛАТЬ:
- ❌ Удалять предметы с существующими заказами
- ❌ Изменять статусы заказов без уведомлений
- ❌ Обходить проверки остатков предметов
- ❌ Давать доступ к чужим данным
- ❌ Игнорировать ошибки валидации
- ❌ Сохранять пароли в открытом виде
- ❌ Пропускать логирование критических операций
- ❌ Блокировать интерфейс без индикации загрузки
- ❌ Создавать брак или продукт без связи с родительским товаром
- ❌ Создавать отдельные типы расходников (только общий тип "РАСХОДНИКИ")
- ❌ Разрешать заказ брака
- ❌ Нарушать иерархию типов предметов
- ❌ Пропускать промежуточные статусы в workflow
- ❌ Нарушать обязательную последовательность модулей в статистике фулфилмента
- ❌ Использовать неправильные имена полей GraphQL (
getMyCounterparties
вместоmyCounterparties
) - ❌ Использовать GET_SUPPLY_SUPPLIERS для отображения поставщиков в формах (только партнеры WHOLESALE)
- ❌ Создавать интерфейсы TypeScript не соответствующие schema.prisma (
sku
/stock
вместоarticle
/quantity
) - ❌ Использовать общие запросы вместо специализированных (
GET_ALL_PRODUCTS
вместоGET_ORGANIZATION_PRODUCTS
для конкретного поставщика) - ❌ Показывать расходники в формах создания поставок товаров (строгая типизация
PRODUCT
/CONSUMABLE
) - ❌ Фильтровать предметы по типу на фронтенде (фильтрация должна быть в GraphQL резолвере)
- ❌ ИСПОЛЬЗОВАТЬ МОКОВЫЕ ДАННЫЕ БЕЗ РАЗРЕШЕНИЯ - все компоненты ОБЯЗАТЕЛЬНО должны использовать реальные GraphQL запросы. Моковые данные можно добавлять ТОЛЬКО с явного разрешения пользователя
- ❌ ДОБАВЛЯТЬ ПОЛЕ РЫНКА К ТОВАРАМ - рынок принадлежит организации поставщика (
Organization.market
), товары наследуют рынок через связь с организацией - ❌ ПУТАТЬ РЫНОК И МАРКЕТ - РЫНОК = физическое место (Садовод, ТЯК), МАРКЕТ = раздел системы (/market)
- ❌ ИСПОЛЬЗОВАТЬ НАЗВАНИЯ ОРГАНИЗАЦИЙ В ЛОГИКЕ БЕЗОПАСНОСТИ - проверки доступа только по
organization.type
и системным ID - ❌ СОЗДАВАТЬ УСЛОВИЯ НА ОСНОВЕ ПОЛЬЗОВАТЕЛЬСКИХ СТРОК - никаких
if (name.includes())
для определения функционала - ❌ ПУТАТЬ ДАННЫЕ И ФУНКЦИОНАЛ - "ОПТ Маркет" (название рынка) ≠ "Маркет" (раздел системы)
- ❌ ПРЕДСТАВЛЯТЬ ИНТЕРПРЕТАЦИИ КАК ФАКТЫ - всегда четко разделять прямые цитаты из правил и логические выводы
- ❌ ОТВЕЧАТЬ БЕЗ ССЫЛОК НА ИСТОЧНИКИ - при ссылке на правила всегда указывать номер строки или раздел
- ❌ ИСПОЛЬЗОВАТЬ КАТЕГОРИЧНЫЕ УТВЕРЖДЕНИЯ БЕЗ ДОКАЗАТЕЛЬСТВ - избегать "ТОЧНО!", "ИМЕННО ТАК!" без прямых цитат
17.2 ОБЯЗАТЕЛЬНЫЕ ПРАВИЛА:
- ✅ Проверка остатков перед добавлением в корзину
- ✅ Валидация всех числовых значений (цена > 0, вес > 0)
- ✅ Автоматическая генерация уникальных артикулов СФ
- ✅ Логирование всех изменений статусов
- ✅ Уведомления всех участников при изменении статусов
- ✅ Обязательная типизация всех предметов
- ✅ Связь производных типов с родительскими предметами
- ✅ Проверка доступности товаров перед заказом
- ✅ Соблюдение жизненного цикла статусов поставок
- ✅ Фиксация план/факт в процессе создания продукта
- ✅ УКАЗЫВАТЬ ИСТОЧНИКИ ИНФОРМАЦИИ - при ссылке на правила обязательно указывать строку/раздел
- ✅ РАЗДЕЛЯТЬ ФАКТЫ И ИНТЕРПРЕТАЦИИ - четко маркировать что взято из правил, а что является выводом
- ✅ ИСПОЛЬЗОВАТЬ ОСТОРОЖНЫЕ ФОРМУЛИРОВКИ - "согласно правилам", "возможно", "требует уточнения"
17.3 📝 ОБЯЗАТЕЛЬНЫЙ ФОРМАТ ОТВЕТОВ С ФАКТАМИ
При ссылке на правила ОБЯЗАТЕЛЬНО использовать формат:
✅ ПРАВИЛЬНО:
📖 ФАКТ из rules-complete.md (строка 2225): "установка цены за единицу"
🧠 МОЯ ИНТЕРПРЕТАЦИЯ: возможно, это происходит в разделе X
❓ ПРЕДПОЛОЖЕНИЕ: требует уточнения у пользователя
⚠️ НЕ НАЙДЕНО в правилах: информация о точном местоположении
❌ НЕПРАВИЛЬНО:
"Да! Точно понимаю! Фулфилмент устанавливает цены в разделе X!"
ОБЯЗАТЕЛЬНАЯ МАРКИРОВКА:
- 📖 ФАКТ - прямая цитата из правил с номером строки
- 🧠 ИНТЕРПРЕТАЦИЯ - мой логический вывод (четко обозначен)
- ❓ ПРЕДПОЛОЖЕНИЕ - гипотеза, требующая подтверждения
- ⚠️ НЕ НАЙДЕНО - информация отсутствует в правилах
СТОП-СЛОВА (избегать без доказательств): ❌ "ТОЧНО!", "ИМЕННО ТАК!", "ДА! ПОНИМАЮ!", "АБСОЛЮТНО ВЕРНО!" ✅ "Согласно правилам...", "Не указано, но возможно...", "Требует уточнения"
17.4 🔒 ПРАВИЛА БЕЗОПАСНОСТИ: Разделение данных и функционала
КРИТИЧЕСКОЕ ПРАВИЛО БЕЗОПАСНОСТИ
ПРИНЦИП: Названия организаций, рынков и любые пользовательские данные НИКОГДА не должны влиять на функционал и безопасность системы.
ОБЯЗАТЕЛЬНЫЕ ПРАВИЛА:
✅ ПРАВИЛЬНЫЕ ПРОВЕРКИ:
- Проверки доступа ТОЛЬКО по типу организации:
organization.type === 'WHOLESALE'
- Роутинг ТОЛЬКО по предопределенным путям:
/market
,/supplies
и т.д. - Валидация ТОЛЬКО по ID и системным полям
- Фильтрация ТОЛЬКО по enum значениям из схемы
❌ ЗАПРЕЩЕННЫЕ ПРОВЕРКИ (УЯЗВИМОСТИ):
- Использование
organization.name
в условиях доступа - Проверки по
organization.market
для определения функционала - Любые проверки содержимого строк:
includes()
,startsWith()
,match()
- Динамическое создание путей на основе пользовательских данных
ПРИМЕРЫ:
// ❌ УЯЗВИМОСТЬ - название может быть любым
if (organization.name.includes('Маркет')) {
// предоставить специальный доступ
}
// ❌ УЯЗВИМОСТЬ - пользователь может подделать название
if (organization.market === 'special-market') {
// изменить цены
}
// ✅ БЕЗОПАСНО - проверка по системному типу
if (organization.type === 'WHOLESALE') {
// логика для поставщиков
}
// ✅ БЕЗОПАСНО - проверка по ID из whitelist
if (ALLOWED_FULFILLMENT_IDS.includes(organization.id)) {
// логика для проверенных фулфилментов
}
РАЗДЕЛЕНИЕ КОНТЕКСТОВ:
-
ДАННЫЕ (могут быть любыми):
- Названия организаций: "ОПТ Маркет", "Супер Склад", и т.д.
- Названия рынков: "Садовод", "ТЯК Москва", любые другие
- Любые пользовательские строки
-
ФУНКЦИОНАЛ (строго определен):
- Системные разделы:
/market
,/supplies
,/partners
- Типы организаций:
WHOLESALE
,SELLER
,FULFILLMENT
,LOGIST
- Статусы и enum из Prisma схемы
- Системные разделы:
ПРАВИЛО: Физический рынок "ОПТ Маркет" - это просто строка данных. Раздел "Маркет" (/market) - это системный функционал. Они никак не связаны и не должны влиять друг на друга.
17.5 📦 УПРАВЛЕНИЕ СВЯЗЯМИ ТОВАР-КАРТОЧКА В РЕЦЕПТУРЕ
17.5.1 Общие принципы
НАЗНАЧЕНИЕ: Связь товара с карточкой маркетплейса - это метаданные для учета, НЕ влияющие на физический состав продукта.
ФОРМУЛА ПРОДУКТА НЕИЗМЕННА:
ПРОДУКТ = Товар + Услуга(и) + Расходники селлера + Расходники ФФ
СВЯЗЬ С МП = отдельные метаданные для логистики и учета
17.5.2 UI компонент связи с карточками
РАСПОЛОЖЕНИЕ: В форме создания поставки, в секции каждого товара
ТИП КОМПОНЕНТА: Dropdown с поиском и фильтрацией
ИСТОЧНИК ДАННЫХ: База данных карточек маркетплейсов селлера (GraphQL запрос)
17.5.3 Логика состояний карточек
✅ СВЯЗАНО - карточка уже привязана к этому товару:
- Показывать зеленую галочку
- Текст: "Название карточки - Связано"
- Можно отвязать (сброс в "Без привязки")
⚠️ ДОСТУПНО - карточка свободна для привязки:
- Показывать желтый значок предупреждения
- Текст: "Название карточки - Доступно"
- Можно привязать к текущему товару
❌ ЗАНЯТО - карточка привязана к другому товару:
- Показывать красный крестик
- Текст: "Название карточки - Занято (товар: 'Название')"
- Пункт заблокирован (disabled)
- Показывать для информации, но нельзя выбрать
🔍 БЕЗ ПРИВЯЗКИ - товар не связан с карточкой:
- Пункт по умолчанию
- Показывать серый значок
- Текст: "Без привязки к карточке"
17.5.4 Техническая реализация
GraphQL запрос:
query GetSellerCards {
myMarketplaceCards {
id
title
marketplace
article
linkedProductId # null если свободна
linkedProduct {
# для отображения занятости
id
name
}
}
}
Логика фильтрации:
- Все карточки селлера показываются в dropdown
- Статус определяется по полю
linkedProductId
- Автосвязка: карточки с похожим названием показываются первыми
Сохранение:
- При создании поставки связь сохраняется в поле
marketplaceCardId
рецептуры - При изменении связи обновляется поле
linkedProductId
в карточке
17.5.5 UX поведение
ПОИСК В DROPDOWN:
- Фильтрация по названию карточки
- Фильтрация по артикулу маркетплейса
- Автофокус при открытии
ГРУППИРОВКА:
[Dropdown: Выберите карточку Wildberries ▼]
├─ 🔍 БЕЗ ПРИВЯЗКИ
├─ ────── ДОСТУПНЫЕ ──────
├─ ⚠️ "Кроссовки Nike Air" - Доступно
├─ ⚠️ "Футболка Adidas" - Доступно
├─ ────── СВЯЗАННЫЕ ──────
├─ ✅ "Джинсы Levi's" - Связано
├─ ────── ЗАНЯТЫЕ ──────
└─ ❌ "Куртка Puma" - Занято (товар "Верхняя одежда") [disabled]
ВАЛИДАЦИЯ:
- Связь опциональна - можно создать поставку без привязки
- При выборе занятой карточки показывать предупреждение
- При отвязке подтверждать действие
17.5.6 Интеграция с существующими правилами
СОВМЕСТИМОСТЬ:
- Не нарушает существующую логику создания поставок
- Дополняет рецептуру метаданными
- Совместима с типами поставок (карточки/поставщики)
ОБЯЗАТЕЛЬНОСТЬ:
- Связь с карточкой - ОПЦИОНАЛЬНА
- Товар может существовать без привязки к МП
- Карточка может существовать без привязки к товару
ПРИОРИТЕТ РАЗРАБОТКИ: Средний (не блокирует основную функциональность)
18. 🛠️ GRAPHQL И TYPESCRIPT ПРАВИЛА
18.1 Правила именования полей
ВАЖНО: Имена полей в GraphQL запросах должны точно соответствовать схеме!
// ✅ ПРАВИЛЬНО - соответствует схеме
export const GET_MY_COUNTERPARTIES = gql`
query GetMyCounterparties {
myCounterparties { // <- имя поля в схеме
id
name
type
}
}
`
// Использование в компоненте
const allCounterparties = counterpartiesData?.myCounterparties || []
// ❌ НЕПРАВИЛЬНО - не соответствует схеме
const allCounterparties = counterpartiesData?.getMyCounterparties || [] // Ошибка!
18.2 Правила отладки GraphQL
При проблемах с GraphQL запросами следовать чек-листу:
- Проверить соответствие имен полей схеме
- Добавить fetchPolicy: 'network-only' для обхода кеша
- Логировать данные в браузере и сервере
- Проверить авторизацию пользователя
- Убедиться что резолвер вызывается
18.3 Обязательные поля для отладки
const { data, loading, error } = useQuery(QUERY_NAME, {
fetchPolicy: 'network-only', // Обходим кеш при отладке
errorPolicy: 'all', // Показываем все ошибки
})
// Логирование для отладки
console.log('Data:', data)
console.log('Loading:', loading)
console.log('Error:', error)
18.4 TypeScript Rules
Интерфейсы данных
Поля интерфейсов должны соответствовать GraphQL схеме:
// ✅ ПРАВИЛЬНО - соответствует schema.prisma
interface GoodsProduct {
id: string
name: string
article: string // <- соответствует полю в schema
quantity?: number // <- соответствует полю в schema
organization: {
id: string
name: string
}
}
// ❌ НЕПРАВИЛЬНО - не соответствует schema
interface GoodsProduct {
sku: string // <- в schema поле называется 'article'
stock?: number // <- в schema поле называется 'quantity'
}
18.5 Система партнерства в GraphQL
ПРАВИЛА ИСПОЛЬЗОВАНИЯ ПАРТНЕРСТВА:
- Поставщики в формах берутся только из партнеров с типом
WHOLESALE
- Используется запрос
GET_MY_COUNTERPARTIES
с фильтрацией по типу - НЕ используется
GET_SUPPLY_SUPPLIERS
для отображения поставщиков в формах - Партнерство создается двумя способами: через заказ в маркете или через раздел "Партнеры"
- Двусторонние записи в таблице
Counterparty
при создании партнерства
18.6 Архитектурные принципы GraphQL
- Создавать специализированные резолверы для каждого контекста использования
- Использовать параметризованные запросы (
organizationId
,type
,search
) вместо фильтрации на фронтенде - Добавлять подробное логирование в резолверы для отладки (входные параметры, результаты фильтрации)
- Типы запросов должны отражать бизнес-логику:
organizationProducts
для товаров конкретной организации
18.7 Правила РЫНКОВ и МАРКЕТА
🔍 КРИТИЧЕСКОЕ РАЗДЕЛЕНИЕ:
- РЫНОК 🏪 = физическое место (Садовод, ТЯК)
- МАРКЕТ 🛒 = раздел системы
/market
ПОЛЕ РЫНКА В SCHEMA:
- Organization.market ✅ - поставщик принадлежит физическому рынку
- Product.market ❌ - ЗАПРЕЩЕНО, товары наследуют рынок от организации
- Отображение рынка товаров: через
product.organization.market
- Фильтрация по рынкам: через
organization.market
, НЕ черезproduct.market
ЗАПРОСЫ С РЫНКАМИ:
# ✅ ПРАВИЛЬНО - рынок от организации поставщика
query GetProductsWithMarket {
myProducts {
id
name
organization {
market # Физический рынок поставщика
}
}
}
# ✅ ПРАВИЛЬНО - товары в маркете с информацией о рынке
query GetMarketProducts {
marketProducts {
id
name
organization {
market # Рынок поставщика
name # Название поставщика
}
}
}
МАРКЕТ (/market) ПРАВИЛА:
- Назначение: Глобальный каталог всех товаров
- Фильтрация: По рынкам поставщиков, типам товаров, категориям
- Отображение: Показать рынок поставщика в карточках товаров
- НЕ путать: МАРКЕТ ≠ конкретный физический рынок
- Значения по умолчанию в резолверах для критических параметров (
type: args.type || "PRODUCT"
) - Валидация обязательных параметров на уровне схемы (
organizationId: ID!
) - Кеширование обходить при проблемах через
fetchPolicy: 'network-only'
18.8 GraphQL правила для поля organization в мутациях
18.8.1 Обязательность поля organization
ПРАВИЛО: Все мутации, возвращающие объекты с типом, включающим organization: Organization!
, ДОЛЖНЫ запрашивать это поле.
ПРОБЛЕМА: Apollo Client кэш ожидает поле organization
в ответе, если оно определено в GraphQL типе как обязательное.
18.8.2 Правильное написание мутаций
❌ НЕПРАВИЛЬНО (вызывает ошибку Apollo Client):
mutation UpdateLogistics($id: ID!, $input: LogisticsInput!) {
updateLogistics(id: $id, input: $input) {
success
logistics {
id
fromLocation
# НЕТ поля organization - ОШИБКА кэша!
}
}
}
✅ ПРАВИЛЬНО (работает корректно):
mutation UpdateLogistics($id: ID!, $input: LogisticsInput!) {
updateLogistics(id: $id, input: $input) {
success
logistics {
id
fromLocation
organization {
# ОБЯЗАТЕЛЬНО включить!
id
name
fullName
}
}
}
}
18.8.3 Чек-лист для мутаций
ОБЯЗАТЕЛЬНАЯ ПРОВЕРКА перед созданием мутации:
- ✅ Проверить GraphQL тип возвращаемого объекта
- ✅ Если есть поле
organization: Organization!
- добавить в запрос - ✅ Включить минимальные поля:
id
,name
,fullName
- ✅ Проверить resolver включает
include: { organization: true }
ПРИМЕНЯЕТСЯ К:
CREATE_LOGISTICS
✅ ИсправленоUPDATE_LOGISTICS
✅ ИсправленоCREATE_SERVICE
- проверить при разработкеUPDATE_SERVICE
- проверить при разработке- Все другие мутации с организационными объектами
ОШИБКА БЕЗ ПОЛЯ: Error converting field "organization" of expected non-nullable type
19. 🔧 АРХИТЕКТУРНЫЕ ПРИНЦИПЫ
19.1 Стандарты разработки
- ОБЯЗАТЕЛЬНО: Покрытие тестами критической функциональности
- ПРАВИЛО: Следование принципам SOLID
- ФУНКЦИЯ: Автоматическое тестирование при развертывании
- КАЧЕСТВО: Минимальное покрытие тестами 80%
19.2 Документация
- ОБЯЗАТЕЛЬНО: Документирование всех API методов
- ПРАВИЛО: Комментарии к сложной бизнес-логике
- ФУНКЦИЯ: Автоматическая генерация документации
- СТАНДАРТ: Актуальная техническая документация
19.3 Масштабируемость
- АРХИТЕКТУРА: Модульная структура для легкого расширения
- ПРАВИЛО: Использование индексов для быстрого поиска
- ФУНКЦИЯ: Горизонтальное масштабирование при росте нагрузки
- ПЛАНИРОВАНИЕ: Готовность к увеличению нагрузки в 10 раз
19.4 Безопасность данных
- ОБЯЗАТЕЛЬНО: Шифрование чувствительных данных
- ПРАВИЛО: Аудит всех действий пользователей
- ФУНКЦИЯ: Контроль доступа на уровне API
- БЕЗОПАСНОСТЬ: Двухфакторная аутентификация для критических операций
20. 🎯 ПРАВИЛА КАЧЕСТВА КОДА
20.1 Проверки и валидация
ОБЯЗАТЕЛЬНЫЕ ПРОВЕРКИ:
- ✅ Типизация предметов: каждый предмет имеет один из типов: ТОВАР (
PRODUCT
), РАСХОДНИКИ (CONSUMABLE
), БРАК и ПРОДУКТ (планируются) - ✅ БРАК и ПРОДУКТ имеют обязательную связь с родительским товаром (parentId)
- ✅ Расходники создаются как универсальный тип, классифицируются при заказе
- ✅ В формах создания поставок товаров показываются ТОЛЬКО предметы типа ТОВАР (
PRODUCT
) - ✅ В формах создания поставок расходников показываются ТОЛЬКО предметы типа РАСХОДНИКИ (
CONSUMABLE
) - ✅ Фильтрация по типу предмета происходит на уровне GraphQL резолвера, не на фронтенде
20.2 Workflow статусов
- ✅ Соблюдена последовательность: PENDING → SUPPLIER_APPROVED → CONFIRMED → LOGISTICS_CONFIRMED → SHIPPED → IN_TRANSIT → DELIVERED
- ✅ Нет пропуска промежуточных статусов
- ✅ Каждое изменение статуса сопровождается уведомлением
20.3 Правила доступа
- ✅ Поставщик НЕ может добавлять собственные товары в корзину
- ✅ Заказ брака ЗАПРЕЩЕН
- ✅ Только активные предметы отображаются в маркете
- ✅ Проверка остатков перед добавлением в корзину
21. 🔍 ДИАГНОСТИКА И РЕШЕНИЕ ПРОБЛЕМ
21.1 Правило уточнений
КРИТИЧЕСКИ ВАЖНО: Если я не уверен в выполнении задачи или вижу противоречия в правилах - ОБЯЗАТЕЛЬНО уточнить у пользователя!
21.2 КОГДА УТОЧНЯТЬ:
- Недостаточно информации для правильного выполнения
- Вижу противоречия между правилами
- Задача может нарушить критические правила
- Неясно как применить правило в конкретной ситуации
- Есть сомнения в интерпретации требований
21.3 КАК УТОЧНЯТЬ:
- Четко сформулировать что именно неясно
- Указать какие правила/требования конфликтуют
- Предложить варианты решения если возможно
- Запросить конкретные уточнения
❌ НИКОГДА не делать предположений если есть сомнения!
22. 📋 КАТЕГОРИИ ТОВАРОВ И РАСХОДНИКОВ
22.1 Полный список 28 универсальных категорий товаров
- Одежда и обувь
- Косметика и парфюмерия
- Дом и сад
- Детские товары
- Спорт и отдых
- Электроника
- Книги
- Здоровье
- Автотовары
- Строительство и ремонт
- Продукты питания
- Зоотовары
- Дача, сад и огород
- Канцелярские товары
- Хобби и творчество
- Украшения и аксессуары
- Сумки и чемоданы
- Техника для дома
- Музыкальные инструменты
- Игры и игрушки
- Мебель
- Товары для красоты
- Бытовая химия
- Товары для путешествий
- Медицинские товары
- Религиозные товары
- Антиквариат и коллекционирование
- Прочие товары
22.2 12 специализированных категорий расходников
🎁 1. УПАКОВКА И ЗАЩИТА
- Коробки (различных размеров)
- Пакеты (полиэтиленовые, бумажные, фирменные)
- Пузырчатая пленка, воздушные подушки
- Стрейч-пленка, гофрокартон
- Паллетная пленка, защитные уголки
🏷️ 2. МАРКИРОВКА И ИДЕНТИФИКАЦИЯ
- Этикетки (адресные, штрих-код, QR-код)
- Бирки (ценники, размерники)
- Стикеры и наклейки
- Маркеры и ручки
- Штампы и печати, термоэтикетки
🔧 3. КРЕПЕЖ И СОЕДИНЕНИЕ
- Скотч (прозрачный, цветной, армированный)
- Клей и клеевые составы
- Стяжки пластиковые
- Степлер и скобы
- Веревки и шнуры, стрейч-лента
📄 4. ДОКУМЕНТООБОРОТ И ВКЛАДЫШИ
- Накладные и сопроводительные документы
- Инструкции по эксплуатации
- Гарантийные талоны
- Рекламные буклеты, визитки и флаеры
- Благодарственные письма, купоны и промокоды
🧼 5. ГИГИЕНА И БЕЗОПАСНОСТЬ
- Перчатки (латексные, нитриловые)
- Маски и респираторы
- Антисептики и дезинфекторы
- Салфетки и тряпки
- Фартуки и халаты, бахилы
🛠️ 6. ИНСТРУМЕНТЫ И ПРИСПОСОБЛЕНИЯ
- Ножи и резаки, ножницы
- Линейки и рулетки
- Упаковочные машины (ленточные)
- Дозаторы скотча
- Пистолеты для термоклея
- Весы и мерная тара
🎨 7. БРЕНДИНГ И ДИЗАЙН
- Фирменные пакеты с логотипом
- Брендированные коробки
- Цветная упаковочная бумага
- Ленты и банты
- Наклейки с логотипом компании
- Подарочная упаковка
⚡ 8. СПЕЦИАЛИЗИРОВАННЫЕ МАТЕРИАЛЫ
- Антистатические пакеты
- Влагопоглотители
- Температурные индикаторы
- Хрупкие наклейки
- Пломбы и пломбировочные материалы
- Защита от краж (магнитные датчики)
🏪 9. ТОРГОВОЕ ОБОРУДОВАНИЕ
- Манекены и вешалки
- Ценникодержатели
- Подставки и стойки
- Корзины и тележки
- Зеркала примерочные
- Освещение витрин
🚚 10. ЛОГИСТИКА И СКЛАДИРОВАНИЕ
- Паллеты и поддоны
- Контейнеры и ящики
- Стеллажные системы
- Погрузочные ремни
- Защитные чехлы
- Адресные ярлыки для груза
💻 11. ТЕХНИЧЕСКИЕ РАСХОДНИКИ
- Картриджи для принтеров
- Термоголовки, красящие ленты
- Батарейки для сканеров
- Чистящие средства для техники
- Запчасти для упаковочного оборудования
🎪 12. СЕЗОННЫЕ И ПРАЗДНИЧНЫЕ
- Новогодняя упаковка
- Подарочные мешки
- Праздничные ленты
- Тематические наклейки
- Открытки и поздравления
- Сезонная упаковочная бумага
ПРИМЕЧАНИЕ: Данные категории являются рекомендательными и могут быть адаптированы под специфику конкретного поставщика расходников.
23. 🎖️ ПРИОРИТЕТЫ РАЗРАБОТКИ
23.1 ВЫСОКИЙ ПРИОРИТЕТ:
- 🔴 Безопасность и контроль доступа
- 🔴 Целостность данных и валидация
- 🔴 Корректность статусов поставок
- 🔴 Уведомления участников процесса
- 🔴 Правильная типизация предметов
- 🔴 Связи между товарами и производными типами
23.2 СРЕДНИЙ ПРИОРИТЕТ:
- 🟡 Производительность и оптимизация
- 🟡 Пользовательский опыт
- 🟡 Аналитика и отчетность
- 🟡 Интеграции с внешними системами
- 🟡 Workflow для брака и продуктов
- 🟡 Разделение расходников по типам
23.3 НИЗКИЙ ПРИОРИТЕТ:
- 🟢 Дополнительные фильтры
- 🟢 Косметические улучшения
- 🟢 Экспериментальные функции
- 🟢 Расширенная кастомизация
🚨 КРИТИЧЕСКИЕ СИТУАЦИИ И EDGE CASES
🔴 Отмена заказов на разных этапах workflow
PENDING → Отмена разрешена
- Действие: Удаление заказа без последствий
- Уведомления: Поставщику о отмене
- Влияние на статистику: Нет
SUPPLIER_APPROVED → Отмена с согласия поставщика
- Действие: Требуется подтверждение поставщика
- Штрафы: Возможны согласно договору
- Восстановление: Товары возвращаются в доступные остатки
CONFIRMED/LOGISTICS_CONFIRMED → Отмена критическая
- Действие: Требуется согласие всех участников
- Штрафы: Логистические расходы
- Альтернатива: Изменение адреса доставки
SHIPPED/IN_TRANSIT → Отмена невозможна
- Действие: Только возврат после получения
- Процедура: Через модуль "Возвраты с ПВЗ"
🔄 Частичная доставка товаров
Сценарий: Поставщик доставил 80 из 100 заказанных единиц
Алгоритм обработки:
- Фулфилмент фиксирует фактическое количество
- Система создает два отдельных документа:
- DELIVERED (80 единиц) - обрабатывается обычным порядком
- PARTIAL_DELIVERED (20 единиц) - остается в статусе ожидания
- Селлер получает уведомление о частичной поставке
- Принятие решения: ждать остаток или отменить недопоставку
📊 Превышение лимитов остатков
Проблема: Попытка заказать больше чем есть у поставщика
Техническая реализация:
if (requestedQuantity > availableStock) {
throw new GraphQLError(`Недостаточно товара. Доступно: ${availableStock}, запрошено: ${requestedQuantity}`)
}
UX решение: Real-time валидация в формах заказа
🔍 Дубликаты артикулов
Сценарий: Поставщик пытается создать товар с существующим артикулом
Проверка на уровне БД:
UNIQUE INDEX ON products(article, organization_id)
Обработка: Автоматическое добавление суффикса или предложение изменить артикул
24. 📎 ТЕХНИЧЕСКИЕ ПРИЛОЖЕНИЯ
Приложение A: GraphQL запросы фулфилмента
// Основные запросы
GET_MY_SERVICES // Услуги фулфилмента
GET_MY_LOGISTICS // Логистические маршруты
GET_MY_EMPLOYEES // Сотрудники организации
GET_FULFILLMENT_WAREHOUSE_STATS // Статистика склада
GET_WAREHOUSE_PRODUCTS // Товары на складе
GET_MY_FULFILLMENT_SUPPLIES // Расходники фулфилмента
GET_EMPLOYEE_SCHEDULE // Табель рабочего времени
// Мутации
;(CREATE_SERVICE, UPDATE_SERVICE, DELETE_SERVICE)
;(CREATE_LOGISTICS, UPDATE_LOGISTICS, DELETE_LOGISTICS)
;(CREATE_EMPLOYEE, UPDATE_EMPLOYEE, DELETE_EMPLOYEE)
UPDATE_EMPLOYEE_SCHEDULE // Обновление табеля
Приложение B: Компоненты фулфилмента
// Основные dashboard компоненты
FulfillmentWarehouseDashboard // Склад фулфилмента
FulfillmentStatisticsDashboard // Статистика
ServicesDashboard // Услуги (3 вкладки)
EmployeesDashboard // Сотрудники
SuppliesDashboard // Поставки фулфилмента
// Специализированные компоненты
;(ServicesTab, LogisticsTab, SuppliesTab) // Вкладки услуг
;(EmployeeInlineForm, EmployeeEditInlineForm) // Формы сотрудников
;(FulfillmentSuppliesTab, FulfillmentConsumablesOrdersTab) // Поставки
Приложение C: Специальный роутинг для типов организаций
const handleSuppliesClick = () => {
switch (user?.organization?.type) {
case 'FULFILLMENT':
router.push('/fulfillment-supplies') // Специальный роут
break
case 'SELLER':
router.push('/supplies')
break
case 'WHOLESALE':
router.push('/wholesale-supplies')
break
case 'LOGIST':
router.push('/logist-supplies')
break
}
}
Эта база знаний создана путем объединения rules-unified.md (v3.0) и fulfillment-cabinet-rules.md (v1.0) с устранением всех несоответствий и добавлением критически важных улучшений: быстрый справочник, глоссарий терминов, детальные алгоритмы процессов, edge cases.
Версия: 10.2
Дата создания: 2025
Статус: ЕДИНЫЙ ИСТОЧНИК ИСТИНЫ - ГОТОВ К РАЗРАБОТКЕ
🚀 УЛУЧШЕНИЯ v6.0:
- ⚡ Быстрый справочник критических правил
- 🔤 Полный глоссарий терминов с определениями
- 🎯 Навигация по ролям (разработчики, аналитики, менеджеры)
- 🔄 Детальный алгоритм создания продукта с временными рамками
- 🚨 Раздел критических ситуаций и Edge Cases
- 📌 Связующие блоки между разделами
- 📊 Таблицы SLA и временных рамок
🔧 ИСПРАВЛЕНИЯ v6.1:
- ✅ Устранено противоречие в моменте создания БРАКА
- ✅ Исправлена логическая цепочка: рецептура задается селлером ДО процесса
- ✅ Реалистичные временные рамки SLA (рабочие дни вместо часов)
- ✅ Унифицирована классификация расходников (по назначению при использовании)
- ✅ Согласованы все алгоритмы и процессы между разделами
🔧 ОБНОВЛЕНИЯ v6.3:
- ✅ ДОБАВЛЕН КРИТИЧЕСКИЙ ЗАПРЕТ: Использование моковых данных в продакшене
- ✅ ОБНОВЛЕН ЧЕКЛИСТ: Добавлена проверка на отсутствие mock данных
- ✅ РЕАЛИЗАЦИЯ: Полная очистка моковых данных из раздела "Мои поставки" селлера
🎨 ИНТЕГРАЦИЯ v6.2:
- ✅ Синхронизация с visual-design-rules.md v1.1
- ✅ Добавлены визуальные правила для 8 статусов поставок
- ✅ Создана цветовая система для 6 модулей фулфилмента
- ✅ Визуальный workflow процесса создания продукта
- ✅ Перекрестные ссылки между техническими и визуальными правилами
- ✅ Покрытие визуальными решениями увеличено с 40% до 85%
🚀 КОНСОЛИДАЦИЯ v7.0:
- ✅ Интеграция development-checklist.md и CLAUDE.md
- ✅ Удаление дублирующих файлов
- ✅ Создание единого источника истины
🔧 ПОЛНАЯ ИНТЕГРАЦИЯ v8.0:
- ✅ Интеграция work-protocols.md (детальные протоколы по сложности)
- ✅ Интеграция violation-prevention-protocol.md (СТОП-сигналы и триггеры)
- ✅ Интеграция self-validation.md (расширенная система самопроверки)
- ✅ Удаление всех дублирующих файлов протоколов
🎯 ОПТИМИЗАЦИЯ UI/UX v8.1:
- ✅ Добавлен ТРИГГЕР #3 для автоматической активации visual-design-rules.md
- ✅ Интегрирован специальный UI/UX протокол в чеклист
- ✅ Создана система перекрестных ссылок с visual-design-rules.md
- ✅ visual-design-rules.md остается отдельным специализированным файлом
📊 ИНТЕГРАЦИЯ DESCRIPTION v9.0:
- ✅ Добавлена UI структура создания поставки расходников (3 блока)
- ✅ Интегрирована концепция многоуровневых таблиц
- ✅ Добавлен механизм учета ПЛАН/ФАКТ в процессе создания продукта
- ✅ Расширена детализация рецептуры продукта
- ✅ Добавлена опция места хранения готовых продуктов
🔧 УТОЧНЕНИЯ ЛОГИКИ v9.1:
- ✅ Уточнен статус брака: НЕ РЕАЛИЗОВАНО (еще не дошли до этого этапа)
- ✅ Добавлены четкие правила создания предметов по ролям
- ✅ Добавлен экономический учет расходников фулфилмента для селлера
- ✅ Обновлен механизм ПЛАН/ФАКТ: потери вместо брака при пересчете
- ✅ Добавлена заметка о будущей детализации статусов товаров
🎨 UI УЛУЧШЕНИЯ v9.2:
- ✅ Добавлены детальные правила горизонтального скролла для блока поставщиков
- ✅ Реализован горизонтальный скролл в create-suppliers-supply-page.tsx
- ✅ Добавлена адаптивность (десктоп 280px, планшет 260px, мобильный 240px)
- ✅ Интегрированы ARIA атрибуты для доступности
- ✅ Реализовано автоскрытие полосы прокрутки и навигация клавиатурой
🔒 БЕЗОПАСНОСТЬ И ТЕРМИНОЛОГИЯ v10.0:
- ✅ ДОБАВЛЕН РАЗДЕЛ 17.3: Правила безопасности - разделение данных и функционала
- ✅ НОВЫЕ ЗАПРЕТЫ 24-26: Запрет использования пользовательских данных в логике безопасности
- ✅ РАСШИРЕН ГЛОССАРИЙ: Контекстно-зависимые термины для SupplyOrder
- ✅ УТОЧНЕНИЕ ТЕРМИНОВ: Четкое разделение "Маркет" (раздел) vs "Маркетплейс" (внешние площадки)
- ✅ ПРИМЕРЫ УЯЗВИМОСТЕЙ: Конкретные примеры безопасного и небезопасного кода
📝 КАЧЕСТВО ОТВЕТОВ v10.1:
- ✅ НОВЫЕ ЗАПРЕТЫ 27-29: Запрет представления интерпретаций как фактов
- ✅ ОБЯЗАТЕЛЬНЫЙ ФОРМАТ ОТВЕТОВ 17.3: Четкое разделение фактов, интерпретаций и предположений
- ✅ СИСТЕМА МАРКИРОВКИ: 📖 ФАКТ, 🧠 ИНТЕРПРЕТАЦИЯ, ❓ ПРЕДПОЛОЖЕНИЕ, ⚠️ НЕ НАЙДЕНО
- ✅ СТОП-СЛОВА: Список категоричных утверждений для избегания без доказательств
- ✅ ОБЯЗАТЕЛЬНЫЕ ПРАВИЛА 11-13: Указание источников и осторожные формулировки
🔗 ПАРТНЕРСКАЯ И РЕФЕРАЛЬНАЯ СИСТЕМА v10.2:
- ✅ ДОБАВЛЕН РАЗДЕЛ 13.6: Критическое различие партнерских и реферальных ссылок
- ✅ ЧЕТКИЕ ОПРЕДЕЛЕНИЯ: Партнерские (?partner=) vs Реферальные (?ref=) ссылки
- ✅ ТЕХНИЧЕСКИЕ ПРАВИЛА: Различия в обработке кодов в резолверах
- ✅ UI СПЕЦИФИКАЦИИ: Разные интерфейсы для партнерства и маркетинга
- ✅ ЗАПРЕТЫ ПУТАНИЦЫ: Строгие правила именования и терминологии
- ✅ ПРИМЕРЫ СЦЕНАРИЕВ: Деловое партнерство vs маркетинговые кампании