feat(fulfillment-supplies): миграция формы создания поставок расходников на v2 систему

- Обновлена форма создания поставок расходников фулфилмента для использования v2 GraphQL API
- Заменена мутация CREATE_SUPPLY_ORDER на CREATE_FULFILLMENT_CONSUMABLE_SUPPLY
- Обновлена структура input данных под новый формат v2
- Сделано поле логистики опциональным
- Добавлено поле notes для комментариев к поставке
- Обновлены refetchQueries на новые v2 запросы
- Исправлены TypeScript ошибки в интерфейсах
- Удалена дублирующая страница consumables-v2
- Сохранен оригинальный богатый UI интерфейс формы (819 строк)
- Подтверждена работа с новой таблицей FulfillmentConsumableSupplyOrder

Технические изменения:
- src/components/fulfillment-supplies/create-fulfillment-consumables-supply-v2.tsx - основная форма
- src/components/fulfillment-supplies/fulfillment-supplies-layout.tsx - обновлена навигация
- Добавлены недостающие поля quantity и ordered в интерфейсы продуктов
- Исправлены импорты и зависимости

Результат: форма полностью интегрирована с v2 системой поставок, которая использует отдельные таблицы для каждого типа поставок согласно новой архитектуре.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Veronika Smirnova
2025-08-25 07:52:46 +03:00
parent d05f0a6a93
commit 0e3ffc179c
34 changed files with 5795 additions and 565 deletions

View File

@ -0,0 +1,487 @@
# 🚚 АРХИТЕКТУРА СИСТЕМЫ ПОСТАВОК SFERA
## 🎯 ОБЗОР СИСТЕМЫ
Система поставок SFERA включает **5 типов поставок**, разделенных на две категории:
### 📦 **ПОСТАВКИ НА ФУЛФИЛМЕНТ (3 типа)**
1. **Товарные поставки** - товары селлера → склад ФФ
2. **Поставки расходников ФФ** - расходники ФФ → склад ФФ
3. **Поставки расходников селлеров** - расходники селлера → склад ФФ (на хранение)
### 🛒 **ПОСТАВКИ НА МАРКЕТПЛЕЙСЫ (2+ типов)**
4. **Поставки на Ozon** - готовые продукты со склада ФФ → Ozon
5. **Поставки на Wildberries** - готовые продукты со склада ФФ → Wildberries
---
## 📊 АРХИТЕКТУРА ДАННЫХ
### ✅ **ПРИНЦИП: ОТДЕЛЬНАЯ ТАБЛИЦА ДЛЯ КАЖДОГО ТИПА ПОСТАВКИ**
#### **Преимущества подхода:**
- 🎯 Четкое разделение ответственности
- 🔒 Упрощение системы безопасности
- 📈 Независимые схемы для разных процессов
- 🔧 Простота миграций и изменений
- 📝 Специфичные поля для каждого типа
### 🏗️ **СТРУКТУРА ТАБЛИЦ ПОСТАВОК НА ФУЛФИЛМЕНТ**
#### **1. GoodsSupplyOrder - Товарные поставки**
```typescript
interface GoodsSupplyOrder {
// === БАЗОВЫЕ ПОЛЯ ===
id: string
status: SupplyOrderStatus
createdAt: DateTime
updatedAt: DateTime
// === ДАННЫЕ СЕЛЛЕРА (создатель) ===
sellerId: string // кто заказывает
fulfillmentCenterId: string // куда доставить
requestedDeliveryDate: DateTime // когда нужно
// === ДАННЫЕ ПОСТАВЩИКА ===
supplierId: string // кто поставляет
supplierApprovedAt?: DateTime // когда одобрил
packagesCount?: number // количество грузомест
estimatedVolume?: number // объем груза
supplierContractId?: string // номер договора
// === ДАННЫЕ ЛОГИСТИКИ ===
logisticsPartnerId?: string // кто везет
estimatedDeliveryDate?: DateTime // план доставки
routeId?: string // маршрут
logisticsCost?: number // стоимость доставки
// === ДАННЫЕ ОТГРУЗКИ ===
shippedAt?: DateTime // факт отгрузки
// === ДАННЫЕ ПРИЕМКИ ===
receivedAt?: DateTime // факт приемки
receivedById?: string // кто принял (сотрудник ФФ)
actualQuantity?: number // принято количество
defectQuantity?: number // брак
// === УНИКАЛЬНЫЕ ПОЛЯ ДЛЯ ТОВАРОВ ===
hasRecipes: boolean // есть ли рецептуры
totalServicesValue?: number // стоимость услуг ФФ
// === СВЯЗИ ===
items: GoodsSupplyItem[]
}
interface GoodsSupplyItem {
id: string
supplyOrderId: string // связь с поставкой
productId: string // какой товар
requestedQuantity: number // запросили
approvedQuantity?: number // поставщик одобрил
shippedQuantity?: number // отгрузили
receivedQuantity?: number // приняли
defectQuantity?: number // брак
unitPrice: number // цена за единицу
totalPrice: number // общая стоимость
// === РЕЦЕПТУРА (JSON) ===
recipe?: {
services: string[] // ID услуг ФФ
fulfillmentConsumables: string[] // ID расходников ФФ
sellerConsumables: string[] // ID расходников селлера
marketplaceCardId?: string // карточка товара
}
}
```
#### **2. FulfillmentConsumableSupplyOrder - Поставки расходников ФФ**
```typescript
interface FulfillmentConsumableSupplyOrder {
// === БАЗОВЫЕ ПОЛЯ ===
id: string
status: SupplyOrderStatus
createdAt: DateTime
updatedAt: DateTime
// === ДАННЫЕ ФФ (создатель) ===
fulfillmentCenterId: string // кто заказывает
requestedDeliveryDate: DateTime // когда нужно
// === ДАННЫЕ ПОСТАВЩИКА ===
supplierId: string // кто поставляет
supplierApprovedAt?: DateTime // когда одобрил
packagesCount?: number // количество грузомест
estimatedVolume?: number // объем груза
supplierContractId?: string // номер договора
// === ДАННЫЕ ЛОГИСТИКИ ===
logisticsPartnerId?: string // кто везет
estimatedDeliveryDate?: DateTime // план доставки
routeId?: string // маршрут
logisticsCost?: number // стоимость доставки
// === ДАННЫЕ ОТГРУЗКИ ===
shippedAt?: DateTime // факт отгрузки
// === ДАННЫЕ ПРИЕМКИ ===
receivedAt?: DateTime // факт приемки
receivedById?: string // кто принял (сотрудник ФФ)
actualQuantity?: number // принято количество
defectQuantity?: number // брак
// === УНИКАЛЬНЫЕ ПОЛЯ ДЛЯ РАСХОДНИКОВ ФФ ===
resalePricePerUnit?: number // цена продажи селлерам
minStockLevel?: number // складские лимиты
// === СВЯЗИ ===
items: FulfillmentConsumableSupplyItem[]
}
interface FulfillmentConsumableSupplyItem {
id: string
supplyOrderId: string // связь с поставкой
productId: string // какой расходник
requestedQuantity: number // запросили
approvedQuantity?: number // поставщик одобрил
shippedQuantity?: number // отгрузили
receivedQuantity?: number // приняли
defectQuantity?: number // брак
unitPrice: number // цена за единицу от поставщика
totalPrice: number // общая стоимость
}
```
#### **3. SellerConsumableSupplyOrder - Поставки расходников селлеров**
```typescript
interface SellerConsumableSupplyOrder {
// === БАЗОВЫЕ ПОЛЯ ===
id: string
status: SupplyOrderStatus
createdAt: DateTime
updatedAt: DateTime
// === ДАННЫЕ СЕЛЛЕРА (создатель) ===
sellerId: string // кто заказывает
fulfillmentCenterId: string // где будет храниться
requestedDeliveryDate: DateTime // когда нужно
// === ДАННЫЕ ПОСТАВЩИКА ===
supplierId: string // кто поставляет
supplierApprovedAt?: DateTime // когда одобрил
packagesCount?: number // количество грузомест
estimatedVolume?: number // объем груза
supplierContractId?: string // номер договора
// === ДАННЫЕ ЛОГИСТИКИ ===
logisticsPartnerId?: string // кто везет
estimatedDeliveryDate?: DateTime // план доставки
routeId?: string // маршрут
logisticsCost?: number // стоимость доставки
// === ДАННЫЕ ОТГРУЗКИ ===
shippedAt?: DateTime // факт отгрузки
// === ДАННЫЕ ПРИЕМКИ ===
receivedAt?: DateTime // факт приемки ФФ
receivedById?: string // кто принял (сотрудник ФФ)
actualQuantity?: number // принято количество
defectQuantity?: number // брак
// === УНИКАЛЬНЫЕ ПОЛЯ ДЛЯ РАСХОДНИКОВ СЕЛЛЕРОВ ===
storageTermMonths?: number // срок хранения
accessRights: 'SELLER_ONLY' | 'SHARED_WITH_FF' // кто может использовать
storageCostPerMonth?: number // стоимость хранения
// === СВЯЗИ ===
items: SellerConsumableSupplyItem[]
}
interface SellerConsumableSupplyItem {
id: string
supplyOrderId: string // связь с поставкой
productId: string // какой расходник селлера
requestedQuantity: number // запросили
approvedQuantity?: number // поставщик одобрил
shippedQuantity?: number // отгрузили
receivedQuantity?: number // приняли
defectQuantity?: number // брак
unitPrice: number // цена за единицу
totalPrice: number // общая стоимость
}
```
### 🛒 **СТРУКТУРА ТАБЛИЦ ПОСТАВОК НА МАРКЕТПЛЕЙСЫ**
#### **4. OzonSupplyOrder - Поставки на Ozon**
```typescript
interface OzonSupplyOrder {
// === БАЗОВЫЕ ПОЛЯ ===
id: string
status: MarketplaceSupplyStatus
createdAt: DateTime
updatedAt: DateTime
// === СПЕЦИФИЧНЫЕ ПОЛЯ OZON ===
ozonWarehouseId: string // склад Ozon
ozonSupplyId?: string // ID поставки в системе Ozon
// ... дополнительные поля для Ozon API
// === СВЯЗИ ===
items: OzonSupplyItem[]
}
```
#### **5. WildberriesSupplyOrder - Поставки на Wildberries**
```typescript
interface WildberriesSupplyOrder {
// === БАЗОВЫЕ ПОЛЯ ===
id: string
status: MarketplaceSupplyStatus
createdAt: DateTime
updatedAt: DateTime
// === СПЕЦИФИЧНЫЕ ПОЛЯ WB ===
wbWarehouseId: string // склад WB
wbSupplyId?: string // ID поставки в системе WB
// ... дополнительные поля для WB API
// === СВЯЗИ ===
items: WildberriesSupplyItem[]
}
```
---
## 🔐 СИСТЕМА БЕЗОПАСНОСТИ
### 📋 **ПРАВИЛА ДОСТУПА К ПОСТАВКАМ РАСХОДНИКОВ ФФ**
**Кто видит и что:**
-**ФФ (создатель):** все детали + цены + остатки
-**Поставщик:** товары, количества, НЕ цены продажи ФФ
-**Логистика:** маршруты, объемы, НЕ коммерческие данные
-**Селлеры:** вообще не видят
### 📋 **ПРАВИЛА ДОСТУПА К ПОСТАВКАМ РАСХОДНИКОВ СЕЛЛЕРОВ**
**Кто видит и что:**
-**Селлер (создатель):** все свои детали + свои цены
-**ФФ (хранитель):** факт хранения + количества, НЕ закупочные цены селлера
-**Поставщик:** товары, количества для селлера
-**Логистика:** маршруты, объемы
-**Другие селлеры:** не видят чужие расходники
### 📋 **ПРАВИЛА ДОСТУПА К ТОВАРНЫМ ПОСТАВКАМ**
**Кто видит и что:**
-**Селлер (создатель):** все детали своих товаров + рецептуры
-**ФФ (получатель):** товары + рецептуры + услуги, НЕ закупочные цены селлера
-**Поставщик:** товары + количества, НЕ рецептуры и НЕ цены ФФ
-**Логистика:** маршруты + объемы, НЕ коммерческие данные
-**Другие селлеры:** не видят чужие поставки
---
## 🌐 URL-СТРУКТУРА ИНТЕРФЕЙСОВ
### 📦 **ПОСТАВКИ НА ФУЛФИЛМЕНТ**
```
/fulfillment-supplies/goods?status=new # Товар → Новые
/fulfillment-supplies/goods?status=receiving # Товар → Приёмка
/fulfillment-supplies/goods?status=accepted # Товар → Принято
/fulfillment-supplies/ff-consumables # Расходники фулфилмента
/fulfillment-supplies/seller-consumables # Расходники селлеров
/fulfillment-supplies/create-consumables # Создание поставки расходников ФФ
```
### 🛒 **ПОСТАВКИ НА МАРКЕТПЛЕЙСЫ**
```
/marketplace-supplies/ozon # Поставки на Ozon
/marketplace-supplies/wildberries # Поставки на Wildberries
/marketplace-supplies/create-ozon # Создание поставки на Ozon
/marketplace-supplies/create-wildberries # Создание поставки на WB
```
---
## ⚡ GRAPHQL API АРХИТЕКТУРА
### 🎯 **ПРИНЦИП: ОТДЕЛЬНЫЕ ОПЕРАЦИИ ДЛЯ КАЖДОГО ТИПА**
#### **Поставки расходников ФФ:**
```graphql
# Queries
myFulfillmentConsumableSupplies: [FulfillmentConsumableSupplyOrder!]!
fulfillmentConsumableSupply(id: ID!): FulfillmentConsumableSupplyOrder
# Mutations
createFulfillmentConsumableSupply(input: CreateFulfillmentConsumableSupplyInput!): CreateSupplyResult!
updateFulfillmentConsumableSupply(id: ID!, input: UpdateFulfillmentConsumableSupplyInput!): UpdateSupplyResult!
```
#### **Поставки расходников селлеров:**
```graphql
# Queries
mySellerConsumableSupplies: [SellerConsumableSupplyOrder!]!
sellerConsumableSupply(id: ID!): SellerConsumableSupplyOrder
# Mutations
createSellerConsumableSupply(input: CreateSellerConsumableSupplyInput!): CreateSupplyResult!
updateSellerConsumableSupply(id: ID!, input: UpdateSellerConsumableSupplyInput!): UpdateSupplyResult!
```
#### **Товарные поставки:**
```graphql
# Queries
myGoodsSupplies: [GoodsSupplyOrder!]!
goodsSupply(id: ID!): GoodsSupplyOrder
# Mutations
createGoodsSupply(input: CreateGoodsSupplyInput!): CreateSupplyResult!
updateGoodsSupply(id: ID!, input: UpdateGoodsSupplyInput!): UpdateSupplyResult!
```
#### **Поставки на маркетплейсы (отдельная система):**
```graphql
# Queries
myOzonSupplies: [OzonSupplyOrder!]!
myWildberriesSupplies: [WildberriesSupplyOrder!]!
# Mutations
createOzonSupply(input: CreateOzonSupplyInput!): CreateMarketplaceSupplyResult!
createWildberriesSupply(input: CreateWildberriesSupplyInput!): CreateMarketplaceSupplyResult!
```
---
## 🔄 ПЛАН ПОЭТАПНОЙ МИГРАЦИИ
### ✅ **ПРИНЦИПЫ БЕЗОПАСНОЙ МИГРАЦИИ**
- 🛡️ Сохранение работоспособности существующей системы
- 🔄 Система откатов на каждом этапе
- 🧪 Тестирование каждого типа поставки отдельно
- 📝 Модульная архитектура
- ❌ **Удаление старого кода ТОЛЬКО после одобрения пользователя**
### **ЭТАП 1: FulfillmentConsumableSupplyOrder**
#### **1.1 Создание новой модели данных**
```typescript
// Новая таблица параллельно со старой
model FulfillmentConsumableSupplyOrder {
// ... вся структура
}
// Старая таблица остается для совместимости
model SupplyOrder {
// ... существующая структура
}
```
#### **1.2 GraphQL API**
```graphql
# Новые операции
createFulfillmentConsumableSupply()
myFulfillmentConsumableSupplies()
# Старые операции остаются работать
createSupplyOrder() # для других типов
mySupplyOrders() # для других типов
```
#### **1.3 Интерфейс**
- Форма `/fulfillment-supplies/create-consumables` → новая мутация
- Вкладка `/fulfillment-supplies/ff-consumables` → новый запрос
#### **1.4 Тестирование**
- ✅ Создание поставки расходников ФФ
- ✅ Отображение в интерфейсе
- ✅ Безопасность доступа
- ✅ Работа старой системы
### **ЭТАП 2: SellerConsumableSupplyOrder**
- Аналогично этапу 1
- Тестирование + интеграция
### **ЭТАП 3: GoodsSupplyOrder**
- Аналогично этапу 1
- Тестирование + интеграция
### **ЭТАП 4: Очистка (ТОЛЬКО после одобрения)**
- Миграция данных из старых таблиц
- Удаление старого кода
- Обновление документации
---
## 🎯 СТАТУСЫ ПОСТАВОК
### **SupplyOrderStatus (для поставок НА фулфилмент)**
```typescript
enum SupplyOrderStatus {
PENDING // Создана, ждет одобрения поставщика
SUPPLIER_APPROVED // Одобрена поставщиком
LOGISTICS_CONFIRMED // Логистика подтверждена
SHIPPED // Отгружена поставщиком
IN_TRANSIT // В пути
DELIVERED // Доставлена на склад ФФ
CANCELLED // Отменена
}
```
### **MarketplaceSupplyStatus (для поставок НА маркетплейсы)**
```typescript
enum MarketplaceSupplyStatus {
PLANNED // Запланирована
PREPARED // Подготовлена к отгрузке
SHIPPED_TO_MARKETPLACE // Отгружена на маркетплейс
ACCEPTED_BY_MARKETPLACE // Принята маркетплейсом
CANCELLED // Отменена
}
```
---
## 📊 ИНТЕГРАЦИИ
### **Поставки НА фулфилмент:**
- 🏪 **DaData API** - валидация ИНН поставщиков
- 📱 **SMS Aero** - уведомления участникам
- ☁️ **AWS S3** - документы поставок
- 🚚 **Логистические партнеры** - трекинг доставки
### **Поставки НА маркетплейсы:**
- 🛒 **Ozon API** - создание поставок
- 🛍️ **Wildberries API** - создание поставок
- 📦 **Трекинг системы** - статусы доставки
- 💰 **Биллинг системы** - расчет комиссий
---
## 🔍 МОНИТОРИНГ И АУДИТ
### **Коммерческие данные:**
- 📊 Логирование доступа к ценам
- 🔐 Аудит прав доступа по ролям
- 📈 Метрики безопасности
- ⚠️ Алерты на подозрительную активность
### **Операционные метрики:**
- ⏱️ Время выполнения поставок
- 📦 Процент успешных доставок
- 🔄 SLA по статусам
- 📊 Аналитика по типам поставок
---
## ✅ ЗАКЛЮЧЕНИЕ
Новая архитектура системы поставок обеспечивает:
- 🎯 **Четкое разделение** типов поставок
- 🔒 **Надежную безопасность** коммерческих данных
- 📈 **Масштабируемость** для новых маркетплейсов
- 🔧 **Простоту развития** каждого типа независимо
- 🛡️ **Безопасную миграцию** без потери данных
**Следующий шаг:** Поэтапная реализация начиная с `FulfillmentConsumableSupplyOrder`