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:
348
docs/business-processes/SUPPLY_CHAIN_WORKFLOW_V2.md
Normal file
348
docs/business-processes/SUPPLY_CHAIN_WORKFLOW_V2.md
Normal file
@ -0,0 +1,348 @@
|
||||
# 🚚 WORKFLOW ЦЕПОЧКИ ПОСТАВОК SFERA v2.0
|
||||
|
||||
> **⚠️ ВАЖНО:** Этот документ описывает НОВУЮ архитектуру системы поставок с разделением на отдельные типы. Для старой системы см. SUPPLY_CHAIN_WORKFLOW.md
|
||||
|
||||
## 🎯 ОБЗОР НОВОЙ СИСТЕМЫ
|
||||
|
||||
Система поставок SFERA v2.0 включает **5 типов поставок**, разделенных на две категории:
|
||||
|
||||
### 📦 **ПОСТАВКИ НА ФУЛФИЛМЕНТ**
|
||||
- `GoodsSupplyOrder` - товары селлера → склад ФФ
|
||||
- `FulfillmentConsumableSupplyOrder` - расходники ФФ → склад ФФ
|
||||
- `SellerConsumableSupplyOrder` - расходники селлера → склад ФФ
|
||||
|
||||
### 🛒 **ПОСТАВКИ НА МАРКЕТПЛЕЙСЫ**
|
||||
- `OzonSupplyOrder` - готовые продукты → Ozon
|
||||
- `WildberriesSupplyOrder` - готовые продукты → Wildberries
|
||||
|
||||
---
|
||||
|
||||
## 🔄 WORKFLOW ПО ТИПАМ ПОСТАВОК
|
||||
|
||||
### 1️⃣ **WORKFLOW: Поставки расходников ФФ**
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[ФФ создает заказ расходников] --> B[PENDING]
|
||||
B --> C{Поставщик одобряет?}
|
||||
C -->|Да| D[SUPPLIER_APPROVED]
|
||||
C -->|Нет| X[CANCELLED]
|
||||
D --> E{Логистика назначена?}
|
||||
E -->|Да| F[LOGISTICS_CONFIRMED]
|
||||
E -->|Нет| D
|
||||
F --> G[Поставщик отгружает]
|
||||
G --> H[SHIPPED]
|
||||
H --> I[IN_TRANSIT]
|
||||
I --> J[ФФ принимает на склад]
|
||||
J --> K[DELIVERED]
|
||||
|
||||
style A fill:#e1f5fe
|
||||
style K fill:#c8e6c9
|
||||
style X fill:#ffcdd2
|
||||
```
|
||||
|
||||
**Участники:**
|
||||
- 🏭 **Фулфилмент** - создатель, получатель
|
||||
- 🏪 **Поставщик (WHOLESALE)** - одобрение, отгрузка
|
||||
- 🚛 **Логистика (LOGIST)** - доставка
|
||||
|
||||
**Особенности:**
|
||||
- ✅ ФФ видит все детали + устанавливает цены продажи селлерам
|
||||
- ✅ Поставщик видит товары/количества, НЕ видит цены продажи ФФ
|
||||
- ✅ Показывается сразу после создания
|
||||
|
||||
### 2️⃣ **WORKFLOW: Поставки товаров селлера**
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Селлер создает заказ товаров] --> B[PENDING]
|
||||
B --> C{Поставщик одобряет?}
|
||||
C -->|Да| D[SUPPLIER_APPROVED]
|
||||
C -->|Нет| X[CANCELLED]
|
||||
D --> E{Логистика назначена?}
|
||||
E -->|Да| F[LOGISTICS_CONFIRMED]
|
||||
E -->|Нет| D
|
||||
F --> G[Поставщик отгружает]
|
||||
G --> H[SHIPPED]
|
||||
H --> I[IN_TRANSIT]
|
||||
I --> J[ФФ принимает + обрабатывает]
|
||||
J --> K[DELIVERED]
|
||||
|
||||
style A fill:#fff3e0
|
||||
style K fill:#c8e6c9
|
||||
style X fill:#ffcdd2
|
||||
```
|
||||
|
||||
**Участники:**
|
||||
- 🛒 **Селлер** - создатель, владелец товара
|
||||
- 🏪 **Поставщик (WHOLESALE)** - поставка
|
||||
- 🚛 **Логистика (LOGIST)** - доставка
|
||||
- 🏭 **Фулфилмент** - получатель, обработка
|
||||
|
||||
**Особенности:**
|
||||
- ✅ Селлер видит свои товары + рецептуры + закупочные цены
|
||||
- ✅ ФФ видит товары + рецептуры + услуги, НЕ видит закупочные цены селлера
|
||||
- ✅ Поставщик видит товары + количества, НЕ видит рецептуры
|
||||
- ✅ Расходники селлера идут **в состав продукта**, не отслеживаются отдельно
|
||||
|
||||
### 3️⃣ **WORKFLOW: Поставки расходников селлера**
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Селлер заказывает свои расходники] --> B[PENDING]
|
||||
B --> C{Поставщик одобряет?}
|
||||
C -->|Да| D[SUPPLIER_APPROVED]
|
||||
C -->|Нет| X[CANCELLED]
|
||||
D --> E{Логистика назначена?}
|
||||
E -->|Да| F[LOGISTICS_CONFIRMED]
|
||||
E -->|Нет| D
|
||||
F --> G[Поставщик отгружает]
|
||||
G --> H[SHIPPED]
|
||||
H --> I[IN_TRANSIT]
|
||||
I --> J[ФФ принимает НА ХРАНЕНИЕ]
|
||||
J --> K[DELIVERED]
|
||||
|
||||
style A fill:#f3e5f5
|
||||
style K fill:#c8e6c9
|
||||
style X fill:#ffcdd2
|
||||
```
|
||||
|
||||
**Участники:**
|
||||
- 🛒 **Селлер** - создатель, владелец расходников
|
||||
- 🏪 **Поставщик (WHOLESALE)** - поставка
|
||||
- 🚛 **Логистика (LOGIST)** - доставка
|
||||
- 🏭 **Фулфилмент** - хранитель (НЕ владелец)
|
||||
|
||||
**Особенности:**
|
||||
- ✅ Селлер видит свои расходники + закупочные цены
|
||||
- ✅ ФФ видит факт хранения + количества, НЕ видит закупочные цены селлера
|
||||
- ✅ Срок хранения + права доступа настраиваются
|
||||
- ✅ Используются селлером в рецептурах своих товаров
|
||||
|
||||
---
|
||||
|
||||
## 📊 СТАТУСЫ И ПЕРЕХОДЫ
|
||||
|
||||
### **SupplyOrderStatus (поставки НА фулфилмент)**
|
||||
|
||||
| Статус | Описание | Ответственный | Действия |
|
||||
|--------|----------|---------------|----------|
|
||||
| `PENDING` | Ожидает одобрения поставщика | Поставщик | Одобрить/Отклонить |
|
||||
| `SUPPLIER_APPROVED` | Одобрено поставщиком | Логистика | Назначить маршрут |
|
||||
| `LOGISTICS_CONFIRMED` | Логистика подтверждена | Поставщик | Отгрузить товар |
|
||||
| `SHIPPED` | Отгружено | Система | Автоматический переход |
|
||||
| `IN_TRANSIT` | В пути | Логистика | Отслеживание доставки |
|
||||
| `DELIVERED` | Доставлено | ФФ | Принять на склад |
|
||||
| `CANCELLED` | Отменено | Любой участник | Указать причину |
|
||||
|
||||
### **MarketplaceSupplyStatus (поставки НА маркетплейсы)**
|
||||
|
||||
| Статус | Описание | Ответственный | Действия |
|
||||
|--------|----------|---------------|----------|
|
||||
| `PLANNED` | Запланирована | ФФ | Подготовить товары |
|
||||
| `PREPARED` | Подготовлена | ФФ | Отгрузить |
|
||||
| `SHIPPED_TO_MARKETPLACE` | Отгружена | Маркетплейс | Принять товар |
|
||||
| `ACCEPTED_BY_MARKETPLACE` | Принята | Система | Обновить остатки |
|
||||
| `CANCELLED` | Отменена | ФФ/Маркетплейс | Указать причину |
|
||||
|
||||
---
|
||||
|
||||
## 🎭 РОЛИ И ПРАВА ДОСТУПА
|
||||
|
||||
### 🏭 **ФУЛФИЛМЕНТ**
|
||||
|
||||
**Может создавать:**
|
||||
- ✅ Поставки расходников ФФ
|
||||
- ✅ Поставки на маркетплейсы
|
||||
|
||||
**Может видеть:**
|
||||
- ✅ Свои поставки расходников: все детали + цены продажи
|
||||
- ✅ Товарные поставки селлеров: товары + рецептуры, НЕ закупочные цены
|
||||
- ✅ Расходники селлеров на хранении: количества, НЕ закупочные цены
|
||||
|
||||
### 🛒 **СЕЛЛЕР**
|
||||
|
||||
**Может создавать:**
|
||||
- ✅ Товарные поставки
|
||||
- ✅ Поставки расходников селлера
|
||||
|
||||
**Может видеть:**
|
||||
- ✅ Свои товарные поставки: все детали + рецептуры + закупочные цены
|
||||
- ✅ Свои расходники: все детали + закупочные цены
|
||||
- ❌ Чужие поставки
|
||||
- ❌ Поставки расходников ФФ
|
||||
|
||||
### 🏪 **ПОСТАВЩИК (WHOLESALE)**
|
||||
|
||||
**Может видеть:**
|
||||
- ✅ Заказы к себе: товары + количества
|
||||
- ❌ Рецептуры товаров
|
||||
- ❌ Цены продажи ФФ селлерам
|
||||
- ❌ Услуги ФФ
|
||||
|
||||
### 🚛 **ЛОГИСТИКА (LOGIST)**
|
||||
|
||||
**Может видеть:**
|
||||
- ✅ Маршруты + объемы + вес
|
||||
- ❌ Коммерческие данные (цены, услуги)
|
||||
- ❌ Рецептуры товаров
|
||||
|
||||
---
|
||||
|
||||
## 🌐 ИНТЕРФЕЙСЫ СИСТЕМЫ
|
||||
|
||||
### 📦 **Кабинет фулфилмента**
|
||||
|
||||
**URL:** `/fulfillment-supplies/`
|
||||
|
||||
**Вкладки:**
|
||||
- `ff-consumables` - поставки расходников ФФ (создание + просмотр)
|
||||
- `seller-consumables` - расходники селлеров на хранении
|
||||
- `goods?status=new` - новые товарные поставки
|
||||
- `goods?status=receiving` - товары в приемке
|
||||
- `goods?status=accepted` - принятые товары
|
||||
|
||||
### 🛒 **Кабинет селлера**
|
||||
|
||||
**URL:** `/seller-supplies/`
|
||||
|
||||
**Вкладки:**
|
||||
- `my-goods` - мои товарные поставки
|
||||
- `my-consumables` - мои расходники
|
||||
- `create-goods` - создать поставку товаров
|
||||
- `create-consumables` - заказать расходники
|
||||
|
||||
### 🛍️ **Кабинет маркетплейсов**
|
||||
|
||||
**URL:** `/marketplace-supplies/`
|
||||
|
||||
**Вкладки:**
|
||||
- `ozon` - поставки на Ozon
|
||||
- `wildberries` - поставки на Wildberries
|
||||
- `create-ozon` - создать поставку на Ozon
|
||||
- `create-wildberries` - создать поставку на WB
|
||||
|
||||
---
|
||||
|
||||
## ⚡ ОСОБЕННОСТИ РЕАЛИЗАЦИИ
|
||||
|
||||
### 🔄 **Дополнение данных по этапам**
|
||||
|
||||
Каждая поставка - это **одна запись**, которая дополняется участниками:
|
||||
|
||||
```typescript
|
||||
// Создание (селлер/ФФ)
|
||||
supply = {
|
||||
id: "...",
|
||||
status: "PENDING",
|
||||
sellerId: "...", // кто создал
|
||||
requestedDate: "...", // когда нужно
|
||||
items: [...] // что заказано
|
||||
}
|
||||
|
||||
// Одобрение (поставщик)
|
||||
supply = {
|
||||
...supply,
|
||||
status: "SUPPLIER_APPROVED",
|
||||
supplierId: "...", // кто одобрил
|
||||
approvedAt: "...", // когда одобрил
|
||||
packagesCount: 5, // уточненные параметры
|
||||
estimatedVolume: 2.5
|
||||
}
|
||||
|
||||
// Назначение логистики (ФФ)
|
||||
supply = {
|
||||
...supply,
|
||||
status: "LOGISTICS_CONFIRMED",
|
||||
logisticsPartnerId: "...", // кто повезет
|
||||
routeId: "...", // маршрут
|
||||
logisticsCost: 1500 // стоимость
|
||||
}
|
||||
```
|
||||
|
||||
### 🔐 **Фильтрация по безопасности**
|
||||
|
||||
Каждый resolver применяет фильтрацию по роли:
|
||||
|
||||
```typescript
|
||||
// Пример: поставки расходников ФФ
|
||||
const supplies = await prisma.fulfillmentConsumableSupplyOrder.findMany({
|
||||
where: {
|
||||
// Только свои поставки для ФФ
|
||||
fulfillmentCenterId: user.organizationId
|
||||
}
|
||||
})
|
||||
|
||||
// Фильтрация полей по роли
|
||||
return supplies.map(supply =>
|
||||
SupplyDataFilter.filterByRole(supply, user.organizationType)
|
||||
)
|
||||
```
|
||||
|
||||
### 📈 **Масштабируемость**
|
||||
|
||||
Новые типы поставок добавляются независимо:
|
||||
|
||||
```typescript
|
||||
// Будущее: Поставки на Яндекс.Маркет
|
||||
interface YandexMarketSupplyOrder {
|
||||
// специфичные поля для Яндекс.Маркета
|
||||
}
|
||||
|
||||
// Отдельные операции
|
||||
createYandexMarketSupply()
|
||||
myYandexMarketSupplies()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ ПРЕИМУЩЕСТВА НОВОЙ АРХИТЕКТУРЫ
|
||||
|
||||
### 🎯 **Четкое разделение ответственности**
|
||||
- Каждый тип поставки имеет свою логику
|
||||
- Независимая разработка и тестирование
|
||||
- Простота добавления новых типов
|
||||
|
||||
### 🔒 **Надежная безопасность**
|
||||
- Раздельные правила доступа для каждого типа
|
||||
- Невозможно случайно показать чужие данные
|
||||
- Гранулярные права по ролям
|
||||
|
||||
### 📈 **Масштабируемость**
|
||||
- Легко добавлять новые маркетплейсы
|
||||
- Независимые схемы для разных процессов
|
||||
- Оптимизация каждого типа отдельно
|
||||
|
||||
### 🛡️ **Безопасная миграция**
|
||||
- Поэтапное внедрение без остановки системы
|
||||
- Система откатов на каждом этапе
|
||||
- Сохранение работоспособности старой системы
|
||||
|
||||
---
|
||||
|
||||
## 🚀 ПЛАН ВНЕДРЕНИЯ
|
||||
|
||||
### **Phase 1:** FulfillmentConsumableSupplyOrder ⏳
|
||||
- Новая модель данных
|
||||
- GraphQL операции
|
||||
- Интерфейс создания и просмотра
|
||||
- Тестирование
|
||||
|
||||
### **Phase 2:** SellerConsumableSupplyOrder
|
||||
- Аналогично Phase 1
|
||||
- Интеграция с системой хранения
|
||||
|
||||
### **Phase 3:** GoodsSupplyOrder
|
||||
- Самый сложный тип с рецептурами
|
||||
- Миграция существующих товарных поставок
|
||||
|
||||
### **Phase 4:** Поставки на маркетплейсы
|
||||
- Отдельная система для Ozon/WB
|
||||
- API интеграции с маркетплейсами
|
||||
|
||||
### **Phase 5:** Очистка и оптимизация
|
||||
- Миграция старых данных
|
||||
- Удаление устаревшего кода (с одобрения)
|
||||
- Финальная оптимизация
|
||||
|
||||
**Следующий шаг:** Начало реализации Phase 1 - FulfillmentConsumableSupplyOrder
|
487
docs/business-processes/SUPPLY_SYSTEM_ARCHITECTURE.md
Normal file
487
docs/business-processes/SUPPLY_SYSTEM_ARCHITECTURE.md
Normal 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`
|
Reference in New Issue
Block a user