# ПРАВИЛА КАБИНЕТА ФУЛФИЛМЕНТА (FULFILLMENT)
> ⚠️ **ВАЖНО**: Это файл с техническими деталями кабинета фулфилмента.
> Общие бизнес-правила находятся в **[rules-complete.md](./rules-complete.md)**
## Когда использовать этот файл:
- Работа с компонентами `/warehouse`, `/fulfillment-supplies`, `/services`, `/employees`
- GraphQL запросы для фулфилмента
- UI/UX специфика кабинета фулфилмента
- Технические детали реализации услуг и логистики
## 1. 🏭 СТРУКТУРА КАБИНЕТА ФУЛФИЛМЕНТА
### 1.1 Основные разделы
**ФУЛФИЛМЕНТ (`FULFILLMENT`)** имеет доступ к следующим разделам:
- **Склад** (`/warehouse`) - управление товарами по модулям
- **Поставки** (`/fulfillment-supplies`) - обработка поставок
- **Услуги** (`/services`) - управление услугами и расходниками
- **Сотрудники** (`/employees`) - управление персоналом
- **Статистика** (`/fulfillment-statistics`) - аналитика фулфилмента
- **Партнеры** (`/partners`) - управление контрагентами
- **Мессенджер** (`/messenger`) - связь с партнерами
- **Настройки** (`/settings`) - профиль и настройки
- **Экономика** (`/economics`) - финансовая аналитика
### 1.2 Навигация и роутинг
#### При входе в систему:
```typescript
switch (user?.organization?.type) {
case 'FULFILLMENT':
router.push('/warehouse') // Направляем на склад
break
}
```
#### Специальная логика роутинга:
- **МАКСИМАЛЬНЫЕ ПРАВА**: Доступ ко ВСЕМ разделам системы
- **АДАПТИВНАЯ НАВИГАЦИЯ**: Sidebar изменяется в зависимости от типа организации
- **СПЕЦИАЛЬНЫЙ РОУТИНГ**: `/fulfillment-supplies` вместо `/supplies`
> 📖 **Бизнес-логика роутинга**: См. [rules-complete.md#4-система-ролей-и-доступов](./rules-complete.md#4--система-ролей-и-доступов)
## 2. 🎨 UI/UX КОМПОНЕНТЫ
### 2.1 Dashboard компоненты
#### Основные компоненты кабинета:
- `FulfillmentWarehouseDashboard` - склад по модулям
- `FulfillmentSuppliesDashboard` - поставки фулфилмента
- `ServicesManagement` - управление услугами
- `FulfillmentStatistics` - статистика и аналитика
- `EmployeeManagement` - управление сотрудниками
#### Wrapper-компоненты:
- `HomePageWrapper` - маршрутизация по типам организаций
- `EconomicsPageWrapper` - адаптивная экономика по кабинетам
#### Специализированные компоненты:
- `WarehouseModuleCard` - карточка модуля склада
- `ServiceCard` - карточка услуги
- `EmployeeCard` - карточка сотрудника
- `FulfillmentStats` - статистика фулфилмента
- `LogisticsRouteCard` - карточка маршрута доставки
### 2.2 Архитектурные особенности
#### Технические правила отображения:
```tsx
// GraphQL проверки
const { data } = useQuery(GET_FULFILLMENT_DATA, {
skip: user?.organization?.type !== 'FULFILLMENT'
})
// Условное отображение
{user?.organization?.type === "FULFILLMENT" && (
)}
// Адаптивные отступы
const margin = getSidebarMargin()
// Полинг данных для реального времени
const { data } = useQuery(GET_FULFILLMENT_STATS, {
pollInterval: 60000 // Обновление каждую минуту
})
```
### 2.3 Система учета склада (3-уровневая иерархия)
#### Структура данных:
```
🔵 УРОВЕНЬ 1: МАГАЗИНЫ
↓
🟢 УРОВЕНЬ 2: ТОВАРЫ (зеленый - green-500)
↓
🟠 УРОВЕНЬ 3: ВАРИАНТЫ ТОВАРОВ (оранжевый - orange-500)
```
#### Цветовое кодирование:
- Каждый уровень имеет цветной индикатор увеличивающегося размера
- Цветная левая граница с увеличивающимся отступом и толщиной
- Скроллбары в цвете уровня
- Контрастный цвет текста для читаемости
## 3. 📊 ФУНКЦИОНАЛЬНЫЕ ВОЗМОЖНОСТИ
> 📖 **Бизнес-правила**: См. [rules-complete.md#11-кабинет-фулфилмента](./rules-complete.md#11--кабинет-фулфилмента) для правил workflow и процессов
### 3.1 Структура склада по модулям (ОБЯЗАТЕЛЬНАЯ ПОСЛЕДОВАТЕЛЬНОСТЬ)
1. **📦 ПРОДУКТЫ** - готовые к отправке товары
2. **🛒 ТОВАРЫ** - базовые товары от поставщиков
- **"На складе"** - готовы к обработке
- **"В обработке"** - в процессе создания продукта
3. **❌ БРАК** - товары с дефектами, требуют утилизации
4. **↩️ ВОЗВРАТЫ С ПВЗ** - возвращенные товары, к обработке
5. **🎯 РАСХОДНИКИ СЕЛЛЕРОВ** - материалы для селлеров
6. **⚙️ РАСХОДНИКИ ФУЛФИЛМЕНТА** - операционные материалы (КЛИКАБЕЛЬНЫЙ модуль)
### 3.2 Система учета склада
#### Показатели движения (дополнительные значения):
- **ПРИБЫЛО** - количество поступивших на склад за период
- **УБЫЛО** - количество списанных со склада за период
#### Текущие остатки (основные значения):
- **ФОРМУЛА**: Основные значения = Предыдущие остатки + Прибыло - Убыло
- **ОБНОВЛЕНИЕ**: В реальном времени с изменениями за сутки
- **ИСТОЧНИК**: GraphQL query `GET_FULFILLMENT_WAREHOUSE_STATS`
### 3.3 Поставки фулфилмента (`/fulfillment-supplies`)
#### Структура: 2 основные вкладки
**A) 🛒 ПОСТАВКИ ТОВАРОВ**:
- **Детализированные товары ФФ** - планы и факты поставок с маршрутами
- **Товары ФФ** - общие поставки товаров от селлеров
- **Возвраты с ПВЗ** - обработка возвращенных товаров
**B) 🔧 ПОСТАВКИ РАСХОДНИКОВ**:
- **Заказы расходников** - управление заказами от селлеров
- **Расходники селлеров** - материалы для клиентов
- **Создание поставок** - формирование новых поставок расходников
#### Workflow поставок товаров:
1. **Planned** - поставка запланирована
2. **In-transit** - товар в пути
3. **Delivered** - доставлен на склад
4. **Completed** - обработка завершена
### 3.4 Услуги фулфилмента (`/services`)
#### Архитектура интеграции с системой
**СВЯЗЬ С РЕЦЕПТУРАМИ СЕЛЛЕРОВ:**
```
СЕЛЛЕР (создание поставки)
└── Рецептура
├── Товар (от поставщика)
├── Услуги фулфилмента ← CRUD в разделе Услуги
├── Расходники селлера
└── Расходники фулфилмента ← ТОЛЬКО с установленной ценой
↓
ФУЛФИЛМЕНТ (обработка)
├── Входящие поставки → Поставки расходников (создание)
└── Услуги → Расходники (установка цены за единицу)
```
#### Структура: 3 обязательные вкладки
**A) 🛠️ УСЛУГИ** (`defaultValue="services"`):
- **Полный CRUD**: создание, редактирование, удаление услуг
- **Поля**: `name`, `description`, `price`, `imageUrl`
- **Glass Upload Zone**: элегантная загрузка изображений
- **Назначение**: каталог услуг для рецептур селлеров
**B) 🚚 ЛОГИСТИКА**:
- **Полный CRUD**: маршруты доставки
- **Поля**: откуда → куда, тарификация до/свыше 1м³
- **Группированные локации**:
- Мой фулфилмент (название организации)
- Рынки (предустановленные)
- Склады Wildberries
- Склады Ozon
- **Glass Upload Zone**: для изображений маршрутов
**C) 📦 РАСХОДНИКИ** (**❌ БЕЗ СОЗДАНИЯ**):
- **ТОЛЬКО ПРОСМОТР** расходников с фулфилмент-склада
- **ЕДИНСТВЕННОЕ РЕДАКТИРУЕМОЕ ПОЛЕ**: `pricePerUnit` - цена за единицу для рецептур
- **UI подсветка**: "Цена за 1 {unit}" (например, "Цена за 1 шт")
- **Автоматическая синхронизация** при приеме поставки расходников
- **Glass Upload Zone**: для обновления изображений расходников
#### Workflow расходников:
**ШАГ 1 - СОЗДАНИЕ**: Только через "Входящие поставки → Поставки расходников фулфилмента"
**ШАГ 2 - СИНХРОНИЗАЦИЯ**: При приеме на склад → автоматически в Услуги/Расходники
**ШАГ 3 - ЦЕНООБРАЗОВАНИЕ**: Установка цены за единицу в разделе Услуги
**ШАГ 4 - ИСПОЛЬЗОВАНИЕ**: Доступны в рецептурах селлеров
#### Правила видимости в рецептурах:
**В РЕЦЕПТУРАХ СЕЛЛЕРОВ ПОКАЗЫВАЮТСЯ ТОЛЬКО:**
- `isAvailable = true` (есть на складе)
- `pricePerUnit != null` (цена установлена)
**НЕ ПОКАЗЫВАЮТСЯ:**
- Расходники без цены (`pricePerUnit = null`)
- Удаленные со склада (`isAvailable = false`)
### 3.5 Разделение цен закупки и продажи
**КРИТИЧЕСКОЕ ПРАВИЛО**: Расходники фулфилмента имеют **ДВЕ РАЗНЫЕ ЦЕНЫ**:
1. **ЦЕНА ЗАКУПКИ** (`Supply.price`) - цена покупки у поставщика
2. **ЦЕНА ПРОДАЖИ** (`Supply.pricePerUnit`) - цена продажи селлерам
#### Поля в базе данных:
```prisma
model Supply {
price Decimal @db.Decimal(10, 2) // Цена закупки у поставщика (НЕИЗМЕННАЯ)
pricePerUnit Decimal? @db.Decimal(10, 2) // Цена продажи селлерам (устанавливается фулфилментом)
}
```
#### Правила отображения по разделам:
**РАЗДЕЛ "СКЛАД → РАСХОДНИКИ ФУЛФИЛМЕНТА"**:
- Показывает `Supply.price` (цена закупки)
- Цена ТОЛЬКО ДЛЯ ЧТЕНИЯ, нельзя изменять
- Отражает историческую стоимость приобретения
**РАЗДЕЛ "УСЛУГИ → РАСХОДНИКИ"**:
- Показывает и редактирует `Supply.pricePerUnit` (цена продажи)
- Единственное место где можно изменить цену для селлеров
- Влияет на рецептуры и расчеты для селлеров
#### Бизнес-логика создания:
```typescript
// ПРИ ПОСТУПЛЕНИИ ОТ ПОСТАВЩИКА:
const supply = await prisma.supply.create({
data: {
price: item.price, // Цена поставщика → ЗАФИКСИРОВАНА
pricePerUnit: null, // Цена продажи → ПУСТАЯ
},
})
// УСТАНОВКА ЦЕНЫ ПРОДАЖИ (в разделе "Услуги"):
const updated = await prisma.supply.update({
data: {
pricePerUnit: newPrice, // ТОЛЬКО цена продажи
// price НЕ ТРОГАЕМ - остается цена закупки
},
})
```
### 3.6 Сотрудники фулфилмента (`/employees`)
#### Структура: 2 основные вкладки
**A) 👥 СОТРУДНИКИ** (`defaultValue="combined"`):
**Управление персоналом**:
- **CRUD операции**: создание, редактирование, удаление сотрудников
- **Статусы сотрудников**: `ACTIVE`, `VACATION`, `SICK`, `FIRED`
- **Формы добавления**: Компактная (`showCompactForm`) / Полная форма
- **Поиск и фильтрация** по имени, должности, статусу
**Табель рабочего времени**:
- **Навигация по месяцам**: текущий год/месяц с кнопками ←/→
- **Отметки по дням**: статус дня и количество отработанных часов
**B) 📋 ОТЧЕТЫ** (`value="reports"`):
- **Сводные отчеты** по сотрудникам за период
- **Экспорт данных** табеля
- **Аналитика рабочего времени**
### 3.7 Статистика фулфилмента (`/fulfillment-statistics`)
#### Блоки аналитики (сворачиваемые):
**1. НАКОПЛЕННАЯ СТАТИСТИКА** (`allTime: true`):
- Обработано товаров (общий объем)
- Выявлено брака (всего единиц)
- Поставок получено
- Общий доход (за все время)
- Выполнено заказов (успешных отгрузок)
- Удовлетворенность клиентов (средний рейтинг)
**2. ОТГРУЗКА НА ПЛОЩАДКИ** (`marketplaces: true`):
- Отправлено на Wildberries
- Отправлено на Ozon
- Отправлено на другие площадки
**3. АНАЛИТИКА ПРОИЗВОДИТЕЛЬНОСТИ** (`performance: false`):
- Среднее время обработки (на единицу товара)
- Уровень брака (от общего объема)
- Уровень возвратов (возвраты с площадок)
- Удовлетворенность клиентов
## 4. 🛠️ GRAPHQL API
### 4.1 Основные запросы (Queries)
#### Получение статистики склада:
```graphql
query GetFulfillmentWarehouseStats {
fulfillmentWarehouseStats {
products {
total
received
shipped
}
supplies {
onStock
inProcessing
}
defects {
total
pending
}
returns {
pending
processed
}
}
}
```
#### Получение услуг фулфилмента:
```graphql
query GetMyServices {
myServices {
id
name
description
price
imageUrl
isActive
}
}
```
#### Получение расходников с ценами:
```graphql
query GetMySupplies {
mySupplies {
id
name
price # Цена закупки (read-only)
pricePerUnit # Цена продажи (editable)
unit
isAvailable
warehouseConsumableId
}
}
```
#### Получение логистических маршрутов:
```graphql
query GetMyLogistics {
myLogistics {
id
fromLocation
toLocation
tariffUnder1m3
tariffOver1m3
description
}
}
```
#### Получение сотрудников:
```graphql
query GetEmployees {
employees {
id
name
position
status
schedule {
date
hoursWorked
status
}
}
}
```
### 4.2 Мутации (Mutations)
#### Создание услуги:
```graphql
mutation CreateService($input: ServiceInput!) {
createService(input: $input) {
success
service {
id
name
description
price
organization {
id
name
fullName
}
}
}
}
```
#### Обновление цены расходника:
```graphql
mutation UpdateSupplyPrice($supplyId: ID!, $pricePerUnit: Float!) {
updateSupplyPrice(id: $supplyId, pricePerUnit: $pricePerUnit) {
success
supply {
id
pricePerUnit
isAvailable
}
}
}
```
#### Создание логистического маршрута:
```graphql
mutation CreateLogistics($input: LogisticsInput!) {
createLogistics(input: $input) {
success
logistics {
id
fromLocation
toLocation
tariffUnder1m3
tariffOver1m3
organization {
id
name
fullName
}
}
}
}
```
#### Управление сотрудниками:
```graphql
mutation CreateEmployee($input: EmployeeInput!) {
createEmployee(input: $input) {
success
employee {
id
name
position
status
}
}
}
mutation UpdateEmployeeSchedule($employeeId: ID!, $date: String!, $hoursWorked: Int!, $status: String!) {
updateEmployeeSchedule(employeeId: $employeeId, date: $date, hoursWorked: $hoursWorked, status: $status) {
success
schedule {
date
hoursWorked
status
}
}
}
```
### 4.3 Специальные запросы для рецептур
#### Расходники доступные для рецептур (только с ценой):
```graphql
query GetAvailableSuppliesForRecipe {
availableSuppliesForRecipe {
id
name
pricePerUnit # Только те что != null
unit
imageUrl
}
}
```
#### GraphQL типы:
```graphql
type Supply {
id: ID!
name: String!
price: Float! # Цена закупки (неизменная)
pricePerUnit: Float # Цена продажи (может быть null)
unit: String! # "шт", "кг", "м"
isAvailable: Boolean! # Статус на складе
warehouseConsumableId: ID! # Связь со складом
imageUrl: String
}
type Service {
id: ID!
name: String!
description: String
price: Float!
imageUrl: String
organization: Organization!
}
type Logistics {
id: ID!
fromLocation: String!
toLocation: String!
tariffUnder1m3: Float!
tariffOver1m3: Float!
description: String
organization: Organization!
}
```
## 5. 📁 ТЕХНИЧЕСКИЕ КОМПОНЕНТЫ
### 5.1 Расположение компонентов
```
src/components/
├── fulfillment/ # Компоненты фулфилмента
│ ├── fulfillment-warehouse-dashboard.tsx
│ ├── fulfillment-supplies-dashboard.tsx
│ ├── fulfillment-statistics.tsx
│ └── warehouse-module-card.tsx
├── services/ # Компоненты услуг
│ ├── services-management.tsx
│ ├── service-card.tsx
│ ├── logistics-management.tsx
│ └── consumables-pricing.tsx
├── employees/ # Компоненты сотрудников
│ ├── employee-management.tsx
│ ├── employee-card.tsx
│ ├── employee-schedule.tsx
│ └── employee-reports.tsx
└── economics/ # Экономика
└── fulfillment-economics-page.tsx
```
### 5.2 Страницы (Pages)
```
src/app/
├── warehouse/
│ └── page.tsx # Склад фулфилмента
├── fulfillment-supplies/
│ └── page.tsx # Поставки фулфилмента
├── services/
│ └── page.tsx # Услуги и расходники
├── employees/
│ └── page.tsx # Сотрудники
└── fulfillment-statistics/
└── page.tsx # Статистика
```
## 6. 🚨 ТЕХНИЧЕСКИЕ ПРАВИЛА И ОГРАНИЧЕНИЯ
> 📖 **Workflow процессов**: См. [rules-complete.md#11-кабинет-фулфилмента](./rules-complete.md#11--кабинет-фулфилмента) для бизнес-процессов
### 6.1 Обязательные проверки:
- Проверка типа организации: `organization.type === 'FULFILLMENT'`
- Валидация прав доступа на уровне GraphQL резолверов
- Проверка наличия товаров на складе перед отгрузкой
- Контроль цен расходников перед отображением в рецептурах
### 6.2 Правила безопасности доступа:
#### Контроль на уровне компонентов:
```typescript
{user?.organization?.type === "FULFILLMENT" && (
)}
// Для полинга данных
const { data } = useQuery(GET_FULFILLMENT_STATS, {
skip: user?.organization?.type !== 'FULFILLMENT',
pollInterval: 60000
})
```
#### Проверки в GraphQL резолверах:
```typescript
// Проверка что пользователь - фулфилмент
if (context.user.organization.type !== 'FULFILLMENT') {
throw new Error('Access denied: Fulfillment access required')
}
// Проверка доступа к своим услугам
const service = await prisma.service.findFirst({
where: {
id: serviceId,
organizationId: context.user.organizationId,
},
})
// Обязательное включение organization в ответы
const updated = await prisma.service.update({
where: { id: serviceId },
data: input,
include: { organization: true }, // ОБЯЗАТЕЛЬНО!
})
```
### 6.3 Запрещено:
- Создавать расходники в разделе "Услуги" (только через поставки)
- Изменять цену закупки (`Supply.price`) - она фиксируется при поступлении
- Показывать в рецептурах расходники без установленной цены продажи
- Удалять услуги, используемые в активных рецептурах
### 6.4 Правила создания и ценообразования:
- **Услуги**: Создаются фулфилментом с установленной ценой
- **Расходники**: Создаются только при поступлении от поставщиков
- **Цена продажи**: Устанавливается отдельно в разделе Услуги
- **Логистика**: Тарификация до/свыше 1м³ обязательна
### 6.5 Правила фулфилмента
**ОБЯЗАТЕЛЬНО**:
- Установка цен на расходники перед доступностью селлерам
- Контроль качества товаров при приемке
- Своевременная обработка возвратов
- Ведение учета движения товаров по модулям
- Управление персоналом и рабочим временем
**ЗАПРЕЩЕНО**:
- Отгружать товары без подтверждения наличия
- Создавать расходники минуя систему поставок
- Изменять цены закупки после поступления товара
- Показывать в рецептурах неактивные расходники
- Нарушать последовательность модулей склада
**ИНТЕГРАЦИЯ С ПАРТНЕРАМИ**:
- Фулфилмент видит всех партнеров системы
- Принимает поставки от всех типов организаций
- Предоставляет услуги селлерам через рецептуры
- Все взаимодействия фиксируются в системе уведомлений
### 6.6 АВТОМАТИЧЕСКИЕ ЗАПИСИ В ТАБЛИЦЕ СКЛАДА ПРИ НОВОМ ПАРТНЕРСТВЕ
#### **ПРАВИЛО АВТОСОЗДАНИЯ ЗАПИСЕЙ В СКЛАДЕ**
**ТРИГГЕР**: При создании нового партнерства с селлером (`SELLER`) автоматически создается запись в таблице склада фулфилмента.
**УСЛОВИЕ СРАБАТЫВАНИЯ**:
- Новая организация типа `SELLER` становится партнером фулфилмента
- Создание происходит через любой механизм партнерства:
- Партнерские ссылки (`?partner=REFERRAL_CODE`)
- Коммерческие взаимодействия
- Прямое добавление в контрагенты
#### **АВТОМАТИЧЕСКИ СОЗДАВАЕМЫЕ ДАННЫЕ**
**Структура записи в таблице склада**:
```typescript
// StoreData - верхний уровень (СИНИЙ УРОВЕНЬ)
interface AutoCreatedStoreEntry {
id: string // Генерируется автоматически
storeName: string // Название организации селлера
storeOwner: string // ИНН или название селлера
storeImage?: string // Логотип организации (если есть)
storeQuantity: number // 0 (пока нет поставок)
products: ProductItem[] // Пустой массив изначально
}
```
#### **ЗНАЧЕНИЯ ПО УМОЛЧАНИЮ**:
- **storeName**: `organization.fullName` или `organization.name`
- **storeOwner**: `organization.inn` или `organization.fullName`
- **storeImage**: `organization.logoUrl` (если заполнено)
- **storeQuantity**: `0` (нет поставок)
- **products**: `[]` (пустой массив)
- **Все вложенные количества**: `0`
#### **БИЗНЕС-ЛОГИКА ОБНОВЛЕНИЯ**
**ПРИ ПЕРВОЙ ПОСТАВКЕ ОТ СЕЛЛЕРА**:
```typescript
// Автоматически обновляются значения:
storeEntry.storeQuantity = totalProductsReceived
storeEntry.products = [
{
id: generatedId,
productName: supply.productName,
productQuantity: supply.quantity,
productPlace: supply.warehouseLocation || 'A1-1',
variants: [] // Заполняется при обработке вариантов
}
]
```
**ОТОБРАЖЕНИЕ В ТАБЛИЦЕ СКЛАДА**:
- Новые партнеры отображаются сразу после создания партнерства
- Показывают нулевые значения до первых поставок
- Цветовое кодирование: СИНИЙ уровень (store level)
- Размещаются в самом верху таблицы
#### **ТЕХНИЧЕСКАЯ РЕАЛИЗАЦИЯ**
**GraphQL мутация (автоматический вызов)**:
```graphql
mutation AutoCreateWarehouseEntry($partnerId: ID!) {
autoCreateWarehouseEntry(partnerId: $partnerId) {
success
warehouseEntry {
id
storeName
storeOwner
storeImage
storeQuantity
}
}
}
```
**Триггер на создание партнерства**:
```typescript
// При создании нового партнера-селлера
const createPartnership = async (sellerId: string, fulfillmentId: string) => {
// 1. Создаем партнерство
const partnership = await createPartnership(sellerId, fulfillmentId)
// 2. Автоматически создаем запись в складе
if (partnership.success) {
await autoCreateWarehouseEntry(sellerId)
}
}
```
#### **ПРАВИЛА ОТОБРАЖЕНИЯ**
**В ТАБЛИЦЕ СКЛАДА ФУЛФИЛМЕНТА**:
- ✅ Показывать всех партнеров-селлеров (даже с нулевыми поставками)
- ✅ Новые партнеры размещаются в самом верху таблицы
- ✅ Стандартное цветовое кодирование для всех партнеров
**ЦВЕТОВОЕ КОДИРОВАНИЕ**:
- **Синий уровень** (партнеры): стандартное отображение для всех
- **Обычный белый цвет текста**: для всех партнеров независимо от статуса поставок
**КООРДИНАТНАЯ СИСТЕМА**:
- Новым партнерам резервируется место: `Quantity: 0 | Location: -`
- При первой поставке координаты назначаются: `A1-1`, `A1-2`, и т.д.
#### **ОБЯЗАТЕЛЬНЫЕ ПОЛЯ ДЛЯ ПАРТНЕРОВ**
**МИНИМАЛЬНЫЕ ТРЕБОВАНИЯ**:
```prisma
model Organization {
id String @id @default(cuid())
name String // ОБЯЗАТЕЛЬНО для storeName
fullName String? // Приоритет для storeName
inn String? // Для storeOwner
logoUrl String? // Для storeImage
type OrganizationType // SELLER
}
```
**ВАЛИДАЦИЯ ПРИ СОЗДАНИИ ПАРТНЕРСТВА**:
- Проверка что организация типа `SELLER`
- Проверка что не существует дубликатов в складе
- Генерация уникального ID для записи склада
#### **ИНТЕГРАЦИЯ С СУЩЕСТВУЮЩИМИ КОМПОНЕНТАМИ**
**В компоненте таблицы склада**:
```typescript
// Сортировка: новые партнеры в верху таблицы
const sortStores = (stores: StoreData[]) => {
return stores.sort((a, b) => {
// Новые партнеры (quantity = 0) в самом верху
if (a.storeQuantity === 0 && b.storeQuantity > 0) return -1
if (a.storeQuantity > 0 && b.storeQuantity === 0) return 1
// Остальная сортировка по количеству или дате
return b.storeQuantity - a.storeQuantity
})
}
```
**В GraphQL запросах склада**:
```graphql
query GetWarehouseData {
warehouseData {
stores {
id
storeName
storeOwner
storeImage
storeQuantity
partnershipDate # Для сортировки новых партнеров
products {
# Существующая структура
}
}
}
}
```
> 📖 **Критические запреты**: См. [rules-complete.md#17-критические-запреты](./rules-complete.md#17--критические-запреты)
---
**Последнее обновление**: Август 2025
**Связанные файлы**:
- [rules-complete.md](./rules-complete.md) - Общие бизнес-правила
- [visual-design-rules.md](./visual-design-rules.md) - Визуальные правила