Files
sfera-new/docs/business-processes/SUPPLY_SYSTEM_ARCHITECTURE.md
Veronika Smirnova 0e3ffc179c 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>
2025-08-25 07:52:46 +03:00

487 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🚚 АРХИТЕКТУРА СИСТЕМЫ ПОСТАВОК 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`