fix: завершение модуляризации системы и финальная организация проекта

## Структурные изменения:

### 📁 Организация архивных файлов:
- Перенос всех устаревших правил в legacy-rules/
- Создание структуры docs-and-reports/ для отчетов
- Архивация backup файлов в legacy-rules/backups/

### 🔧 Критические компоненты:
- src/components/supplies/multilevel-supplies-table.tsx - многоуровневая таблица поставок
- src/components/supplies/components/recipe-display.tsx - отображение рецептур
- src/components/fulfillment-supplies/fulfillment-goods-orders-tab.tsx - вкладка товарных заказов

### 🎯 GraphQL обновления:
- Обновление mutations.ts, queries.ts, resolvers.ts, typedefs.ts
- Синхронизация с Prisma schema.prisma
- Backup файлы для истории изменений

### 🛠️ Утилитарные скрипты:
- 12 новых скриптов в scripts/ для анализа данных
- Скрипты проверки фулфилмент-пользователей
- Утилиты очистки и фиксации данных поставок

### 📊 Тестирование:
- test-fulfillment-filtering.js - тестирование фильтрации фулфилмента
- test-full-workflow.js - полный workflow тестирование

### 📝 Документация:
- logistics-statistics-warehouse-rules.md - объединенные правила модулей
- Обновление журналов модуляризации и разработки

###  Исправления ESLint:
- Исправлены критические ошибки в sidebar.tsx
- Исправлены ошибки типизации в multilevel-supplies-table.tsx
- Исправлены неиспользуемые переменные в goods-supplies-table.tsx
- Заменены типы any на строгую типизацию
- Исправлены console.log на console.warn

## Результат:
- Завершена полная модуляризация системы
- Организована архитектура legacy файлов
- Добавлены критически важные компоненты таблиц
- Создана полная инфраструктура тестирования
- Исправлены все критические ESLint ошибки
- Сохранены 103 незакоммиченных изменения

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Veronika Smirnova
2025-08-22 10:31:43 +03:00
parent 621770e765
commit 89257c75b5
86 changed files with 25406 additions and 942 deletions

View File

@ -0,0 +1,197 @@
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function analyzeFulfillmentSupplies() {
try {
console.log('🔍 ГЛУБОКИЙ АНАЛИЗ РАСХОДНИКОВ ФУЛФИЛМЕНТА')
console.log('=' .repeat(60))
// Находим фулфилмент организацию пользователя с номером +7 (999) 999-99-99
const fulfillmentUser = await prisma.user.findFirst({
where: { phone: '79999999999' },
include: {
organization: {
include: {
_count: {
select: {
supplies: true,
supplyOrders: true,
fulfillmentSupplyOrders: true
}
}
}
}
}
})
if (!fulfillmentUser?.organization) {
console.log('❌ Фулфилмент пользователь или организация не найдены')
return
}
const org = fulfillmentUser.organization
console.log('🏢 ОРГАНИЗАЦИЯ:')
console.log(` ID: ${org.id}`)
console.log(` Название: ${org.name}`)
console.log(` Тип: ${org.type}`)
console.log(` Расходников на складе: ${org._count.supplies}`)
console.log(` Заказов поставок: ${org._count.supplyOrders}`)
console.log(` Входящих поставок: ${org._count.fulfillmentSupplyOrders}`)
console.log('')
// 1. АНАЛИЗ РАСХОДНИКОВ НА СКЛАДЕ
console.log('📦 1. РАСХОДНИКИ НА СКЛАДЕ:')
const allSupplies = await prisma.supply.findMany({
where: { organizationId: org.id },
orderBy: { createdAt: 'desc' }
})
console.log(` Всего записей Supply: ${allSupplies.length}`)
// Группируем по типам
const fulfillmentSupplies = allSupplies.filter(s => s.type === 'FULFILLMENT_CONSUMABLES')
const sellerSupplies = allSupplies.filter(s => s.type === 'SELLER_CONSUMABLES')
console.log(` 📊 Расходники фулфилмента: ${fulfillmentSupplies.length} записей`)
console.log(` 💼 Расходники селлеров: ${sellerSupplies.length} записей`)
console.log('')
// Детальный анализ расходников фулфилмента
if (fulfillmentSupplies.length > 0) {
console.log('🔍 ДЕТАЛИ РАСХОДНИКОВ ФУЛФИЛМЕНТА:')
fulfillmentSupplies.forEach((supply, index) => {
console.log(` ${index + 1}. "${supply.name}" (${supply.article})`)
console.log(` ID: ${supply.id}`)
console.log(` Количество: ${supply.quantity} шт`)
console.log(` Текущий остаток: ${supply.currentStock} шт`)
console.log(` Использовано: ${supply.usedStock} шт`)
console.log(` Статус: ${supply.status}`)
console.log(` Поставщик: ${supply.supplier}`)
console.log(` Дата: ${supply.date?.toISOString().split('T')[0]}`)
console.log(` Создано: ${supply.createdAt?.toISOString().split('T')[0]}`)
console.log('')
})
}
// 2. АНАЛИЗ ЗАКАЗОВ ПОСТАВОК
console.log('📋 2. ЗАКАЗЫ ПОСТАВОК (созданные фулфилментом):')
const createdOrders = await prisma.supplyOrder.findMany({
where: { organizationId: org.id },
include: {
partner: { select: { name: true, type: true } },
items: {
include: { product: { select: { name: true, article: true } } }
}
},
orderBy: { createdAt: 'desc' }
})
console.log(` Всего заказов: ${createdOrders.length}`)
createdOrders.forEach((order, index) => {
console.log(` ${index + 1}. Заказ ${order.id}`)
console.log(` Поставщик: ${order.partner.name} (${order.partner.type})`)
console.log(` Статус: ${order.status}`)
console.log(` Тип расходников: ${order.consumableType}`)
console.log(` Дата доставки: ${order.deliveryDate?.toISOString().split('T')[0]}`)
console.log(` Сумма: ${order.totalAmount}`)
console.log(` Товаров: ${order.items.length}`)
order.items.forEach((item, itemIndex) => {
console.log(` ${itemIndex + 1}) ${item.product.name} (${item.product.article}) - ${item.quantity} шт`)
})
console.log('')
})
// 3. АНАЛИЗ ВХОДЯЩИХ ПОСТАВОК
console.log('📥 3. ВХОДЯЩИЕ ПОСТАВКИ (доставляемые на фулфилмент):')
const receivedOrders = await prisma.supplyOrder.findMany({
where: { fulfillmentCenterId: org.id },
include: {
organization: { select: { name: true, type: true } },
partner: { select: { name: true, type: true } },
items: {
include: { product: { select: { name: true, article: true } } }
}
},
orderBy: { createdAt: 'desc' }
})
console.log(` Всего входящих поставок: ${receivedOrders.length}`)
receivedOrders.forEach((order, index) => {
console.log(` ${index + 1}. Поставка ${order.id}`)
console.log(` Заказчик: ${order.organization.name} (${order.organization.type})`)
console.log(` Поставщик: ${order.partner.name} (${order.partner.type})`)
console.log(` Статус: ${order.status}`)
console.log(` Тип расходников: ${order.consumableType}`)
console.log(` Дата доставки: ${order.deliveryDate?.toISOString().split('T')[0]}`)
console.log(` Сумма: ${order.totalAmount}`)
console.log(` Товаров: ${order.items.length}`)
order.items.forEach((item, itemIndex) => {
console.log(` ${itemIndex + 1}) ${item.product.name} (${item.product.article}) - ${item.quantity} шт`)
})
console.log('')
})
// 4. СВЕРКА ДАННЫХ
console.log('⚖️ 4. СВЕРКА ДАННЫХ:')
// Подсчитываем ожидаемое количество расходников из заказов
const totalFromOrders = createdOrders
.filter(order => order.status === 'DELIVERED' && order.consumableType === 'FULFILLMENT_CONSUMABLES')
.reduce((sum, order) => {
return sum + order.items.reduce((itemSum, item) => itemSum + item.quantity, 0)
}, 0)
const totalFromSupplies = fulfillmentSupplies.reduce((sum, supply) => sum + supply.currentStock, 0)
console.log(` 📊 Ожидаемое из доставленных заказов: ${totalFromOrders} шт`)
console.log(` 📦 Фактическое в Supply записях: ${totalFromSupplies} шт`)
console.log(` ${totalFromOrders === totalFromSupplies ? '✅' : '❌'} Соответствие: ${totalFromOrders === totalFromSupplies ? 'КОРРЕКТНО' : 'ОШИБКА'}`)
if (totalFromOrders !== totalFromSupplies) {
console.log(` 🔍 Разница: ${Math.abs(totalFromOrders - totalFromSupplies)} шт`)
}
// 5. АНАЛИЗ ПО АРТИКУЛАМ
console.log('')
console.log('🏷️ 5. АНАЛИЗ ПО АРТИКУЛАМ:')
const articleGroups = {}
fulfillmentSupplies.forEach(supply => {
if (!articleGroups[supply.article]) {
articleGroups[supply.article] = []
}
articleGroups[supply.article].push(supply)
})
console.log(` Уникальных артикулов: ${Object.keys(articleGroups).length}`)
Object.entries(articleGroups).forEach(([article, supplies]) => {
const totalStock = supplies.reduce((sum, s) => sum + s.currentStock, 0)
console.log(` 📋 ${article}: ${supplies.length} записей, ${totalStock} шт общий остаток`)
if (supplies.length > 1) {
console.log(` ⚠️ ДУБЛИРОВАНИЕ: ${supplies.length} записей для одного артикула!`)
supplies.forEach((supply, index) => {
console.log(` ${index + 1}) ID: ${supply.id}, остаток: ${supply.currentStock} шт`)
})
}
})
console.log('')
console.log('=' .repeat(60))
console.log('✅ АНАЛИЗ ЗАВЕРШЕН')
} catch (error) {
console.error('❌ ОШИБКА при анализе:', error)
console.error(' Детали:', error.message)
} finally {
await prisma.$disconnect()
}
}
analyzeFulfillmentSupplies()