debug: добавить скрипты отладки и бэкапы для диагностики проблем

- api_keys_backup_1758196936364.json - резервная копия API ключей
- check-active-key.js - проверка активного API ключа
- check-all-keys.js - проверка всех API ключей в системе
- check-new-seller.js - проверка нового селлера
- test-api-key-save.js - тестирование сохранения API ключей
- test-graphql-stats.js - тестирование GraphQL статистики
- test-resolver-direct.js - прямое тестирование резолверов
- test-sidebar.html - тестирование сайдбара
- test-statistics-direct.js - прямое тестирование статистики

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Veronika Smirnova
2025-09-18 21:32:23 +03:00
parent b6935428ab
commit d19530a985
9 changed files with 853 additions and 0 deletions

View File

@ -0,0 +1,53 @@
{
"timestamp": "2025-09-18T12:02:16.363Z",
"apiKeys": [
{
"id": "cmfo4o2ym000ny5ccj72vkskc",
"marketplace": "WILDBERRIES",
"apiKey": "eyJhbGciOiJFUzI1NiIsImtpZCI6IjIwMjUwNTIwdjEiLCJ0eXAiOiJKV1QifQ.eyJlbnQiOjEsImV4cCI6MTc2NjgwODMzMiwiaWQiOiIwMTk3YjIyMy0xNDAwLTc1MTQtYjgwZS0wYzIyYjRiYWZlODYiLCJpaWQiOjM0MTU5NTU3LCJvaWQiOjI1MDAwOTkxMCwicyI6MTA3Mzc0OTc1OCwic2lkIjoiNTIwMmYwMzYtMWNiNC00MmIyLWFhODUtYWNiOWFjODJmYzYyIiwidCI6ZmFsc2UsInVpZCI6MzQxNTk1NTd9.tSjALISoFdkylX0iMuquXhpRJhTZwEMOZV_mfZh1wXUtRzyu4m8r5cvodaMVxcSNKifit2Vm2CWKw1Hp9z7_AQ",
"clientId": null,
"isActive": true,
"createdAt": "2025-09-17T15:19:35.423Z",
"updatedAt": "2025-09-17T15:19:35.423Z",
"validationData": "{\"sellerId\":\"5202f036-1cb4-42b2-aa85-acb9ac82fc62\",\"sellerName\":\"ИП Антипова Д. В.\",\"tradeMark\":\"Rennel\"}",
"organizationId": "cmfo4o1on000ly5ccsmshxlde",
"organization": {
"id": "cmfo4o1on000ly5ccsmshxlde",
"inn": "SELLER_1758122373766",
"kpp": null,
"name": "Rennel",
"fullName": "ИП Антипова Д. В.",
"ogrn": null,
"ogrnDate": null,
"type": "SELLER",
"market": null,
"createdAt": "2025-09-17T15:19:33.767Z",
"updatedAt": "2025-09-17T15:19:35.598Z",
"address": null,
"addressFull": null,
"status": null,
"actualityDate": null,
"registrationDate": null,
"liquidationDate": null,
"managementName": null,
"managementPost": null,
"opfCode": null,
"opfFull": null,
"opfShort": null,
"okato": null,
"oktmo": null,
"okpo": null,
"okved": null,
"phones": null,
"emails": null,
"employeeCount": null,
"revenue": null,
"taxSystem": null,
"dadataData": null,
"referralCode": "SL_78855599999_1758122373766",
"referredById": "cmfo4jpk1000ay5cc7sunfeso",
"referralPoints": 0
}
}
]
}

47
check-active-key.js Normal file
View File

@ -0,0 +1,47 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function checkActiveKey() {
try {
// Найдем организацию Rennel
const org = await prisma.organization.findFirst({
where: { name: 'Rennel', type: 'SELLER' },
include: {
users: true,
apiKeys: {
where: {
marketplace: 'WILDBERRIES',
isActive: true,
},
orderBy: { createdAt: 'desc' },
},
},
})
if (!org) {
console.log('❌ Организация Rennel не найдена')
return
}
console.log('🏢 ОРГАНИЗАЦИЯ RENNEL:')
console.log('- ID:', org.id)
console.log('- Пользователей:', org.users.length)
console.log('- Активных WB ключей:', org.apiKeys.length)
if (org.apiKeys.length > 0) {
const activeKey = org.apiKeys[0] // Последний созданный
console.log('\n🔑 АКТИВНЫЙ КЛЮЧ (который будет использоваться):')
console.log('- ID:', activeKey.id)
console.log('- Длина:', activeKey.apiKey?.length)
console.log('- Тип:', activeKey.apiKey?.startsWith('eyJ') ? 'Валидный JWT' : 'Тестовый')
console.log('- Создан:', activeKey.createdAt.toISOString())
console.log('- Данные валидации:', JSON.stringify(activeKey.validationData, null, 2))
}
} catch (error) {
console.error('❌ Ошибка:', error)
} finally {
await prisma.$disconnect()
}
}
checkActiveKey()

55
check-all-keys.js Normal file
View File

@ -0,0 +1,55 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function checkAllKeys() {
try {
const org = await prisma.organization.findFirst({
where: { name: 'Rennel', type: 'SELLER' },
include: {
apiKeys: {
where: { marketplace: 'WILDBERRIES' },
orderBy: { createdAt: 'desc' },
},
},
})
if (!org) {
console.log('❌ Организация Rennel не найдена')
return
}
console.log('🏢 ОРГАНИЗАЦИЯ RENNEL:')
console.log('- ID:', org.id)
console.log('- Всего WB ключей:', org.apiKeys.length)
console.log('\n🔍 ВСЕ КЛЮЧИ WILDBERRIES:')
org.apiKeys.forEach((key, index) => {
console.log(`\n--- КЛЮЧ ${index + 1} ---`)
console.log('- ID:', key.id)
console.log('- Длина:', key.apiKey?.length)
console.log('- Тип:', key.apiKey?.startsWith('eyJ') ? 'Валидный JWT' : 'Тестовый')
console.log('- Активен:', key.isActive)
console.log('- Создан:', key.createdAt.toISOString())
console.log('- Обновлен:', key.updatedAt.toISOString())
console.log('- Данные валидации:', JSON.stringify(key.validationData, null, 2))
})
// Найдем самый новый валидный JWT ключ
const validJwtKey = org.apiKeys.find((key) => key.apiKey?.startsWith('eyJ') && key.isActive)
if (validJwtKey) {
console.log('\n✅ НАЙДЕН ВАЛИДНЫЙ JWT КЛЮЧ:')
console.log('- ID:', validJwtKey.id)
console.log('- Создан:', validJwtKey.createdAt.toISOString())
console.log('- Должен использоваться вместо тестового')
} else {
console.log('\n❌ ВАЛИДНЫЙ JWT КЛЮЧ НЕ НАЙДЕН')
}
} catch (error) {
console.error('❌ Ошибка:', error)
} finally {
await prisma.$disconnect()
}
}
checkAllKeys()

71
check-new-seller.js Normal file
View File

@ -0,0 +1,71 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function checkNewSeller() {
try {
// Найдем пользователя с номером 79988888888
const user = await prisma.user.findFirst({
where: { phone: '79988888888' },
include: {
organization: {
include: {
apiKeys: {
where: { marketplace: 'WILDBERRIES' },
orderBy: { createdAt: 'desc' },
},
},
},
},
})
if (!user) {
console.log('❌ Пользователь 79988888888 не найден')
return
}
console.log('👤 НОВЫЙ ПОЛЬЗОВАТЕЛЬ 79988888888:')
console.log('- ID:', user.id)
console.log('- Телефон:', user.phone)
console.log('- Организация:', user.organization?.name || 'НЕ ПРИВЯЗАНА')
if (user.organization) {
console.log('\n🏢 ОРГАНИЗАЦИЯ:')
console.log('- ID:', user.organization.id)
console.log('- Название:', user.organization.name)
console.log('- Тип:', user.organization.type)
console.log('- WB ключей:', user.organization.apiKeys.length)
if (user.organization.apiKeys.length > 0) {
console.log('\n🔑 API КЛЮЧИ WILDBERRIES:')
user.organization.apiKeys.forEach((key, index) => {
console.log(`\n--- КЛЮЧ ${index + 1} ---`)
console.log('- ID:', key.id)
console.log('- Длина:', key.apiKey?.length)
console.log('- Тип:', key.apiKey?.startsWith('eyJ') ? 'Валидный JWT' : 'Тестовый')
console.log('- Активен:', key.isActive)
console.log('- Создан:', key.createdAt.toISOString())
console.log('- Данные валидации:', JSON.stringify(key.validationData, null, 2))
})
// Найдем самый новый валидный ключ
const validKey = user.organization.apiKeys.find((key) => key.apiKey && key.apiKey.length > 100 && key.isActive)
if (validKey) {
console.log('\n✅ СТАТУС: Есть валидный API ключ')
console.log('- Можно получать статистику Wildberries')
} else {
console.log('\n⚠ СТАТУС: Только тестовые ключи')
console.log('- Статистика будет пустой')
}
} else {
console.log('\n❌ API КЛЮЧИ НЕ НАЙДЕНЫ')
}
}
} catch (error) {
console.error('❌ Ошибка:', error)
} finally {
await prisma.$disconnect()
}
}
checkNewSeller()

117
test-api-key-save.js Normal file
View File

@ -0,0 +1,117 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function testApiKeySave() {
try {
console.log('🔍 ТЕСТ СОХРАНЕНИЯ API КЛЮЧА')
// Найдем организацию Rennel
const org = await prisma.organization.findFirst({
where: { name: 'Rennel', type: 'SELLER' },
include: {
apiKeys: {
where: { marketplace: 'WILDBERRIES' },
orderBy: { createdAt: 'desc' },
},
},
})
if (!org) {
console.log('❌ Организация Rennel не найдена')
return
}
console.log('\n📊 СОСТОЯНИЕ ДО ТЕСТА:')
console.log('- Организация:', org.name)
console.log('- Всего WB ключей:', org.apiKeys.length)
if (org.apiKeys.length > 0) {
const currentKey = org.apiKeys[0]
console.log('- Текущий ключ ID:', currentKey.id)
console.log('- Длина:', currentKey.apiKey?.length)
console.log('- Тип:', currentKey.apiKey?.startsWith('eyJ') ? 'JWT' : 'Тестовый')
}
// Тестовый валидный JWT ключ (более короткий для теста)
const testJwtKey =
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FjY291bnQud2lsZGJlcnJpZXMucnUiLCJzdWIiOjEyMzQ1Njc4OTAsImV4cCI6MTcyNjY3MjgwMCwidXNlclR5cGUiOiJzZWxsZXIiLCJzY29wZSI6WyJhZHZlcnRpc2luZyIsInN0YXRpc3RpY3MiLCJvcmRlcnMiXX0.test_signature_here'
console.log('\n🔄 ИМИТАЦИЯ ОБНОВЛЕНИЯ КЛЮЧА...')
// Имитируем обновление через API (как делает мутация)
const existingKey = await prisma.apiKey.findUnique({
where: {
organizationId_marketplace: {
organizationId: org.id,
marketplace: 'WILDBERRIES',
},
},
})
if (existingKey) {
console.log('- Найден существующий ключ:', existingKey.id)
// Обновляем как в мутации
const updated = await prisma.apiKey.update({
where: {
organizationId_marketplace: {
organizationId: org.id,
marketplace: 'WILDBERRIES',
},
},
data: {
apiKey: testJwtKey,
isActive: true,
validationData: { validatedAt: new Date().toISOString() },
},
})
console.log('✅ Ключ обновлен:', updated.id)
console.log('- Новая длина:', updated.apiKey?.length)
console.log('- Новый тип:', updated.apiKey?.startsWith('eyJ') ? 'JWT' : 'Тестовый')
} else {
console.log('- Существующий ключ не найден, создаем новый')
const created = await prisma.apiKey.create({
data: {
organizationId: org.id,
marketplace: 'WILDBERRIES',
apiKey: testJwtKey,
isActive: true,
validationData: { validatedAt: new Date().toISOString() },
},
})
console.log('✅ Новый ключ создан:', created.id)
}
// Проверим результат
console.log('\n📊 СОСТОЯНИЕ ПОСЛЕ ТЕСТА:')
const updatedOrg = await prisma.organization.findFirst({
where: { name: 'Rennel', type: 'SELLER' },
include: {
apiKeys: {
where: { marketplace: 'WILDBERRIES' },
orderBy: { createdAt: 'desc' },
},
},
})
if (updatedOrg && updatedOrg.apiKeys.length > 0) {
const newKey = updatedOrg.apiKeys[0]
console.log('- Ключ ID:', newKey.id)
console.log('- Длина:', newKey.apiKey?.length)
console.log('- Тип:', newKey.apiKey?.startsWith('eyJ') ? 'JWT' : 'Тестовый')
console.log('- Активен:', newKey.isActive)
console.log('- Обновлен:', newKey.updatedAt.toISOString())
}
console.log('\n🎯 ТЕСТ ЗАВЕРШЕН')
} catch (error) {
console.error('❌ ОШИБКА ТЕСТА:', error)
} finally {
await prisma.$disconnect()
}
}
testApiKeySave()

95
test-graphql-stats.js Normal file
View File

@ -0,0 +1,95 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function testGraphQLStats() {
try {
console.log('🔍 ТЕСТИРОВАНИЕ ЛОГИКИ РЕЗОЛВЕРА getWildberriesStatistics')
// Имитируем логику резолвера
const user = await prisma.user.findFirst({
where: { phone: '79988888888' },
include: {
organization: {
include: { apiKeys: true },
},
},
})
if (!user?.organization) {
console.log('❌ Пользователь не привязан к организации')
return
}
console.log('\n👤 ПОЛЬЗОВАТЕЛЬ:')
console.log('- ID:', user.id)
console.log('- Телефон:', user.phone)
console.log('- Организация:', user.organization.name)
// Логика поиска API ключа как в резолвере
const apiKey = user.organization.apiKeys.find((key) => key.marketplace === 'WILDBERRIES' && key.isActive)
console.log('\n🔍 ПОИСК API КЛЮЧА:')
console.log('- Всего ключей в организации:', user.organization.apiKeys.length)
console.log('- Найденный ключ:', !!apiKey)
if (!apiKey) {
console.log('❌ ПРОБЛЕМА: API ключ не найден через find()')
// Выводим все ключи для дебага
user.organization.apiKeys.forEach((key, index) => {
console.log(`\n--- КЛЮЧ ${index + 1} ---`)
console.log('- ID:', key.id)
console.log('- Marketplace:', key.marketplace)
console.log('- Active:', key.isActive)
console.log('- Условие WILDBERRIES:', key.marketplace === 'WILDBERRIES')
console.log('- Условие Active:', key.isActive === true)
console.log('- Полное условие:', key.marketplace === 'WILDBERRIES' && key.isActive)
})
return
}
console.log('\n✅ API КЛЮЧ НАЙДЕН:')
console.log('- ID:', apiKey.id)
console.log('- Marketplace:', apiKey.marketplace)
console.log('- Active:', apiKey.isActive)
console.log('- Длина ключа:', apiKey.apiKey?.length)
console.log('- Тип:', apiKey.apiKey?.startsWith('eyJ') ? 'JWT' : 'Другой')
// Проверим, работает ли сам API ключ
console.log('\n🌐 ТЕСТИРОВАНИЕ ЗАПРОСА К WILDBERRIES API:')
const testUrl = 'https://statistics-api.wildberries.ru/api/v1/supplier/sales?dateFrom=2025-09-01'
try {
const response = await fetch(testUrl, {
headers: {
Authorization: apiKey.apiKey,
'Content-Type': 'application/json',
},
})
console.log('- HTTP статус:', response.status)
console.log('- OK:', response.ok)
if (response.ok) {
const data = await response.json()
console.log('- Данные получены, тип:', typeof data)
console.log('- Является массивом:', Array.isArray(data))
console.log('- Длина:', data?.length || 'N/A')
} else {
const errorText = await response.text()
console.log('- Ошибка API:', errorText)
}
} catch (fetchError) {
console.error('❌ ОШИБКА ЗАПРОСА:', fetchError.message)
}
} catch (error) {
console.error('❌ КРИТИЧЕСКАЯ ОШИБКА:', error)
} finally {
await prisma.$disconnect()
}
}
testGraphQLStats()

114
test-resolver-direct.js Normal file
View File

@ -0,0 +1,114 @@
// Тест резолвера GraphQL getWildberriesStatistics напрямую
const testResolverDirect = async () => {
console.log('🧪 ПРЯМОЙ ТЕСТ РЕЗОЛВЕРА getWildberriesStatistics')
const query = `
query GetWildberriesStatistics($period: String, $startDate: String, $endDate: String) {
getWildberriesStatistics(period: $period, startDate: $startDate, endDate: $endDate) {
success
message
data {
date
sales
orders
advertising
refusals
returns
revenue
buyoutPercentage
}
}
}
`
// Получаем JWT токен (предполагаем что пользователь авторизован)
// Замените на реальный токен из браузера или создайте новый
const JWT_TOKEN = 'YOUR_JWT_TOKEN_HERE'
const variables1 = { period: 'week' }
const variables2 = { startDate: '2025-09-01', endDate: '2025-09-18' }
console.log('\n🔍 ТЕСТ 1: period = "week"')
try {
const response1 = await fetch('http://localhost:3001/api/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${JWT_TOKEN}`,
},
body: JSON.stringify({
query,
variables: variables1,
}),
})
if (response1.ok) {
const result1 = await response1.json()
console.log('✅ Ответ получен:')
console.log('- success:', result1.data?.getWildberriesStatistics?.success)
console.log('- message:', result1.data?.getWildberriesStatistics?.message)
console.log('- data length:', result1.data?.getWildberriesStatistics?.data?.length)
if (result1.errors) {
console.log('❌ GraphQL ошибки:', result1.errors)
}
} else {
console.log('❌ HTTP ошибка:', response1.status)
}
} catch (error) {
console.error('❌ Ошибка запроса:', error.message)
}
console.log('\n🔍 ТЕСТ 2: startDate + endDate')
try {
const response2 = await fetch('http://localhost:3001/api/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${JWT_TOKEN}`,
},
body: JSON.stringify({
query,
variables: variables2,
}),
})
if (response2.ok) {
const result2 = await response2.json()
console.log('✅ Ответ получен:')
console.log('- success:', result2.data?.getWildberriesStatistics?.success)
console.log('- message:', result2.data?.getWildberriesStatistics?.message)
console.log('- data length:', result2.data?.getWildberriesStatistics?.data?.length)
if (result2.data?.getWildberriesStatistics?.data?.length > 0) {
console.log('- Первая запись:', JSON.stringify(result2.data.getWildberriesStatistics.data[0], null, 2))
}
if (result2.errors) {
console.log('❌ GraphQL ошибки:', result2.errors)
}
} else {
console.log('❌ HTTP ошибка:', response2.status)
}
} catch (error) {
console.error('❌ Ошибка запроса:', error.message)
}
}
// Инструкция для пользователя
console.log(`
📋 ИНСТРУКЦИЯ ДЛЯ ЗАПУСКА ТЕСТА:
1. Откройте браузер на http://localhost:3001/seller/statistics
2. Авторизуйтесь под номером 79988888888 (код: 1234)
3. Откройте Developer Tools (F12) → Network → найдите GraphQL запрос
4. Скопируйте заголовок Authorization: Bearer ...
5. Замените JWT_TOKEN в этом файле на реальный токен
6. Запустите: node test-resolver-direct.js
Или используйте этот код прямо в консоли браузера (без токена):
`)
testResolverDirect()

219
test-sidebar.html Normal file
View File

@ -0,0 +1,219 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sidebar Visibility Test</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background: linear-gradient(135deg, #1a0f2e 0%, #2d1b3d 50%, #0f0a1a 100%);
color: white;
min-height: 100vh;
}
.test-sidebar {
position: fixed;
left: 16px;
top: 16px;
bottom: 16px;
width: 224px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 16px;
padding: 12px;
z-index: 50;
display: flex;
flex-direction: column;
}
.profile-section {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 12px;
padding: 10px;
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 10px;
}
.avatar {
width: 28px;
height: 28px;
border-radius: 50%;
background: linear-gradient(135deg, #3b82f6, #8b5cf6);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 12px;
}
.nav-button {
width: 100%;
padding: 8px 12px;
background: rgba(255, 255, 255, 0.1);
border: none;
border-radius: 8px;
color: white;
text-align: left;
margin-bottom: 4px;
cursor: pointer;
transition: all 0.2s;
}
.nav-button:hover {
background: rgba(255, 255, 255, 0.2);
}
.nav-button.active {
background: rgba(255, 255, 255, 0.2);
}
.main-content {
margin-left: 256px;
padding: 20px;
}
.debug-info {
background: rgba(0, 0, 0, 0.5);
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
}
.status {
display: inline-block;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: bold;
}
.status.visible {
background: #10b981;
color: white;
}
.status.hidden {
background: #ef4444;
color: white;
}
</style>
</head>
<body>
<div class="test-sidebar" id="testSidebar">
<div class="profile-section">
<div class="avatar">T</div>
<div>
<div style="font-size: 14px; font-weight: 500;">Test Organization</div>
<div style="font-size: 12px; opacity: 0.7;">Логистика</div>
</div>
</div>
<div style="flex: 1;">
<button class="nav-button active">🏠 Главная</button>
<button class="nav-button">🚛 Перевозки</button>
<button class="nav-button">💬 Мессенджер</button>
<button class="nav-button">💰 Экономика</button>
<button class="nav-button">🤝 Партнёры</button>
<button class="nav-button">🏪 Маркет</button>
<button class="nav-button">📈 Биржа</button>
<button class="nav-button">⚙️ Настройки</button>
</div>
<button class="nav-button" style="margin-top: auto;">🚪 Выйти</button>
</div>
<div class="main-content">
<div class="debug-info">
<h2>🔍 Sidebar Visibility Test</h2>
<p><strong>Статус:</strong> <span class="status visible" id="visibilityStatus">VISIBLE</span></p>
<p><strong>Позиция:</strong> fixed left-16px top-16px</p>
<p><strong>Z-index:</strong> 50</p>
<p><strong>Фон:</strong> rgba(255, 255, 255, 0.1) + backdrop-blur</p>
<p><strong>Размеры:</strong> 224px x auto</p>
</div>
<div class="debug-info">
<h3>🎯 Тесты отображения</h3>
<button onclick="toggleSidebar()" style="background: #3b82f6; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; margin-right: 8px;">
Переключить сайдбар
</button>
<button onclick="checkZIndex()" style="background: #8b5cf6; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; margin-right: 8px;">
Проверить z-index
</button>
<button onclick="testBackdrop()" style="background: #10b981; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer;">
Тест backdrop-filter
</button>
</div>
<div class="debug-info">
<h3>🧪 Результаты проверок</h3>
<div id="testResults">
<p>✅ Sidebar элемент создан и добавлен в DOM</p>
<p>✅ CSS стили применены корректно</p>
<p>✅ Позиционирование fixed работает</p>
<p>✅ Z-index установлен на 50</p>
<p>✅ Backdrop-filter поддерживается браузером</p>
</div>
</div>
<div class="debug-info">
<h3>📊 Проблемы SFERA Sidebar</h3>
<p><strong>1. Условия рендеринга:</strong> Проверьте hideSidebar в AppShell</p>
<p><strong>2. Данные пользователя:</strong> Убедитесь что user?.organization?.type передается</p>
<p><strong>3. TypeScript ошибки:</strong> Исправьте проблемы с isCollapsed в уведомлениях</p>
<p><strong>4. CSS конфликты:</strong> Возможно другие элементы перекрывают z-index: 50</p>
<p><strong>5. SSR проблемы:</strong> dynamic import с ssr: false может вызывать проблемы</p>
</div>
</div>
<script>
function toggleSidebar() {
const sidebar = document.getElementById('testSidebar');
const status = document.getElementById('visibilityStatus');
if (sidebar.style.display === 'none') {
sidebar.style.display = 'flex';
status.textContent = 'VISIBLE';
status.className = 'status visible';
} else {
sidebar.style.display = 'none';
status.textContent = 'HIDDEN';
status.className = 'status hidden';
}
}
function checkZIndex() {
const sidebar = document.getElementById('testSidebar');
const computedStyle = window.getComputedStyle(sidebar);
alert(`Z-index: ${computedStyle.zIndex}\nPosition: ${computedStyle.position}\nDisplay: ${computedStyle.display}`);
}
function testBackdrop() {
const testDiv = document.createElement('div');
testDiv.style.backdropFilter = 'blur(10px)';
document.body.appendChild(testDiv);
const supported = window.getComputedStyle(testDiv).backdropFilter !== '';
document.body.removeChild(testDiv);
alert(`Backdrop-filter support: ${supported ? 'YES' : 'NO'}`);
}
// Автоматическая диагностика при загрузке
window.addEventListener('load', function() {
console.log('=== SIDEBAR VISIBILITY TEST ===');
console.log('Sidebar element:', document.getElementById('testSidebar'));
console.log('Computed styles:', window.getComputedStyle(document.getElementById('testSidebar')));
console.log('Viewport dimensions:', window.innerWidth, 'x', window.innerHeight);
console.log('Backdrop-filter support:', CSS.supports('backdrop-filter', 'blur(1px)'));
});
</script>
</body>
</html>

82
test-statistics-direct.js Normal file
View File

@ -0,0 +1,82 @@
import { PrismaClient } from '@prisma/client'
import { WildberriesService } from './src/services/wildberries-service.js'
const prisma = new PrismaClient()
async function testStatisticsDirect() {
try {
console.log('🔍 ПРЯМОЕ ТЕСТИРОВАНИЕ СТАТИСТИКИ WILDBERRIES')
// Найдем пользователя 79988888888
const user = await prisma.user.findFirst({
where: { phone: '79988888888' },
include: {
organization: {
include: {
apiKeys: {
where: { marketplace: 'WILDBERRIES', isActive: true },
},
},
},
},
})
if (!user?.organization?.apiKeys[0]) {
console.log('❌ API ключ не найден')
return
}
const apiKey = user.organization.apiKeys[0]
console.log('\n🔑 НАЙДЕННЫЙ API КЛЮЧ:')
console.log('- ID:', apiKey.id)
console.log('- Длина:', apiKey.apiKey?.length)
console.log('- Первые 10 символов:', apiKey.apiKey?.substring(0, 10))
console.log('- Активен:', apiKey.isActive)
// Тестируем WildberriesService напрямую
console.log('\n🧪 ТЕСТИРОВАНИЕ WILDBERRIES SERVICE:')
try {
const wbService = new WildberriesService(apiKey.apiKey)
console.log('✅ WildberriesService создан успешно')
// Тестируем получение статистики
const startDate = '2025-09-01'
const endDate = '2025-09-18'
console.log(`\n📊 ЗАПРОС СТАТИСТИКИ (${startDate} - ${endDate}):`)
const statistics = await wbService.getStatistics(startDate, endDate)
console.log('✅ СТАТИСТИКА ПОЛУЧЕНА:')
console.log('- Тип данных:', typeof statistics)
console.log('- Является массивом:', Array.isArray(statistics))
console.log('- Длина:', statistics?.length || 'N/A')
if (Array.isArray(statistics) && statistics.length > 0) {
console.log('- Первая запись:', JSON.stringify(statistics[0], null, 2))
} else {
console.log('- Данные пусты или отсутствуют')
}
} catch (serviceError) {
console.error('❌ ОШИБКА WILDBERRIES SERVICE:', serviceError.message)
console.error('Стек:', serviceError.stack)
}
// Проверим что API ключ имеет правильные права доступа
console.log('\n🔐 ПРОВЕРКА ПРАВ API КЛЮЧА:')
console.log('- Данные валидации:', JSON.stringify(apiKey.validationData, null, 2))
if (apiKey.validationData?.sellerId) {
console.log('✅ SellerId найден:', apiKey.validationData.sellerId)
} else {
console.log('❌ SellerId отсутствует')
}
} catch (error) {
console.error('❌ КРИТИЧЕСКАЯ ОШИБКА:', error)
} finally {
await prisma.$disconnect()
}
}
testStatisticsDirect()