fix: исправить критические ошибки системы партнерских заявок
КРИТИЧЕСКИЕ ИСПРАВЛЕНИЯ: - Исправлено отображение входящих заявок (неправильное извлечение данных) - Устранен ApolloError при принятии заявок (неправильная структура мутаций) - Исправлено отображение контрагентов после принятия заявки - Обновлены типы возврата GraphQL мутаций для соответствия резолверам UI/UX УЛУЧШЕНИЯ: - Обновлены все компоненты на темную glass-morphism тему - Компактные карточки контрагентов (удалена избыточная информация) - Удален дублирующий блок поиска новых партнеров ЗАТРОНУТЫЕ ФАЙЛЫ: - useCounterpartyData.ts: исправлено извлечение данных - useCounterpartyActions.ts: исправлены структуры мутаций - IncomingRequestsBlock.tsx: темная тема + исправления UI - OutgoingRequestsBlock.tsx: темная тема - CounterpartiesListBlock.tsx: компактные карточки + темная тема - typedefs.ts: исправлены типы возврата мутаций 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
347
2025-09-19/PARTNERSHIP_REQUESTS_DEBUG.md
Normal file
347
2025-09-19/PARTNERSHIP_REQUESTS_DEBUG.md
Normal file
@ -0,0 +1,347 @@
|
||||
# 🔍 ДИАГНОСТИКА: ПРОБЛЕМА С ВХОДЯЩИМИ ЗАЯВКАМИ НА ПАРТНЕРСТВО
|
||||
|
||||
> **Дата:** 2025-09-19
|
||||
> **Время:** 22:40
|
||||
> **Проблема:** Пользователь отправил заявку на партнерство, но во входящих ничего нет
|
||||
|
||||
---
|
||||
|
||||
## 🚨 **ОПИСАНИЕ ПРОБЛЕМЫ**
|
||||
|
||||
**Пользователь сообщает:**
|
||||
|
||||
> "я отправил заявку на партнерство - но во входящих ничего нет"
|
||||
|
||||
**Ожидаемое поведение:**
|
||||
|
||||
1. Пользователь A отправляет заявку на партнерство пользователю B
|
||||
2. У пользователя B в разделе "Входящие заявки" должна появиться заявка
|
||||
3. Пользователь B может принять или отклонить заявку
|
||||
|
||||
---
|
||||
|
||||
## 🔧 **ТЕХНИЧЕСКАЯ ДИАГНОСТИКА**
|
||||
|
||||
### ✅ **ПРОВЕРЕННЫЕ КОМПОНЕНТЫ:**
|
||||
|
||||
#### **1. GraphQL Резолвер для входящих заявок:**
|
||||
|
||||
📄 **Файл:** `src/graphql/resolvers/domains/counterparty-management.ts:44`
|
||||
|
||||
```typescript
|
||||
incomingRequests: async (_: unknown, __: unknown, context: Context) => {
|
||||
const currentUser = await getCurrentUser(context)
|
||||
|
||||
const incomingRequests = await prisma.counterpartyRequest.findMany({
|
||||
where: {
|
||||
receiverId: currentUser.organization.id,
|
||||
status: 'PENDING',
|
||||
},
|
||||
include: {
|
||||
sender: { include: { users: true, apiKeys: true } },
|
||||
receiver: { include: { users: true, apiKeys: true } },
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 50,
|
||||
})
|
||||
|
||||
console.warn('📥 INCOMING_REQUESTS:', {
|
||||
userId: currentUser.id,
|
||||
organizationId: currentUser.organization.id,
|
||||
requestsCount: incomingRequests.length,
|
||||
})
|
||||
|
||||
return incomingRequests
|
||||
}
|
||||
```
|
||||
|
||||
**✅ Статус:** Резолвер корректный
|
||||
|
||||
#### **2. GraphQL Резолвер для отправки заявок:**
|
||||
|
||||
📄 **Файл:** `src/graphql/resolvers/domains/counterparty-management.ts:152`
|
||||
|
||||
```typescript
|
||||
sendCounterpartyRequest: async (_, args, context) => {
|
||||
// Проверки:
|
||||
// - Получатель существует
|
||||
// - Не отправляем себе
|
||||
// - Нет активной заявки
|
||||
// - Нет существующего партнерства
|
||||
|
||||
const request = await prisma.counterpartyRequest.create({
|
||||
data: {
|
||||
senderId: currentUser.organization.id,
|
||||
receiverId: args.input.receiverId,
|
||||
message: args.input.message,
|
||||
status: 'PENDING',
|
||||
},
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
**✅ Статус:** Резолвер корректный
|
||||
|
||||
#### **3. Подключение резолверов:**
|
||||
|
||||
📄 **Файл:** `src/graphql/resolvers/index.ts:107`
|
||||
|
||||
```typescript
|
||||
counterpartyManagementResolvers, // ✅ ПОДКЛЮЧЕН
|
||||
```
|
||||
|
||||
**✅ Статус:** Резолвер подключен к системе
|
||||
|
||||
#### **4. GraphQL Запросы:**
|
||||
|
||||
📄 **Файл:** `src/graphql/queries.ts:404`
|
||||
|
||||
```typescript
|
||||
export const GET_INCOMING_REQUESTS = gql`
|
||||
query GetIncomingRequests {
|
||||
incomingRequests {
|
||||
id
|
||||
status
|
||||
message
|
||||
createdAt
|
||||
sender {
|
||||
id
|
||||
inn
|
||||
name
|
||||
fullName
|
||||
type
|
||||
}
|
||||
receiver {
|
||||
id
|
||||
inn
|
||||
name
|
||||
fullName
|
||||
type
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
```
|
||||
|
||||
**✅ Статус:** Запрос корректный
|
||||
|
||||
#### **5. Prisma Модель:**
|
||||
|
||||
📄 **Файл:** `prisma/schema.prisma`
|
||||
|
||||
```prisma
|
||||
model CounterpartyRequest {
|
||||
id String @id @default(cuid())
|
||||
status CounterpartyRequestStatus @default(PENDING)
|
||||
senderId String
|
||||
receiverId String
|
||||
message String?
|
||||
sender Organization @relation("SentRequests")
|
||||
receiver Organization @relation("ReceivedRequests")
|
||||
|
||||
@@unique([senderId, receiverId])
|
||||
}
|
||||
```
|
||||
|
||||
**✅ Статус:** Модель корректная
|
||||
|
||||
#### **6. UI Компонент:**
|
||||
|
||||
📄 **Файл:** `src/components/market/market-counterparties/index.tsx`
|
||||
|
||||
```typescript
|
||||
const {
|
||||
incomingRequests,
|
||||
incomingLoading,
|
||||
} = useCounterpartyData()
|
||||
|
||||
// Подсчет уведомлений
|
||||
const pendingIncomingCount = incomingRequests.filter(req => req.status === 'PENDING').length
|
||||
|
||||
// Таб входящих заявок с индикацией
|
||||
<TabsTrigger value="incoming" className={`
|
||||
${pendingIncomingCount > 0 ? 'animate-pulse ring-2 ring-green-400/50' : ''}
|
||||
`}>
|
||||
```
|
||||
|
||||
**✅ Статус:** UI компонент корректный
|
||||
|
||||
---
|
||||
|
||||
## 🔍 **ВОЗМОЖНЫЕ ПРИЧИНЫ ПРОБЛЕМЫ**
|
||||
|
||||
### **1. 🎭 ПРОБЛЕМА С РОЛЯМИ**
|
||||
|
||||
**Симптом:** Заявка отправляется не от той организации или не тому получателю
|
||||
|
||||
**Диагностика:**
|
||||
|
||||
- Проверить, что отправитель и получатель имеют корректные `organizationId`
|
||||
- Убедиться, что текущий пользователь авторизован правильно
|
||||
|
||||
### **2. 🗃️ ПРОБЛЕМА С БАЗОЙ ДАННЫХ**
|
||||
|
||||
**Симптом:** Заявка создается, но не возвращается в запросе
|
||||
|
||||
**Диагностика:**
|
||||
|
||||
- Проверить, что заявка действительно создалась в БД
|
||||
- Убедиться, что статус заявки `PENDING`
|
||||
- Проверить правильность `receiverId`
|
||||
|
||||
### **3. 🔄 ПРОБЛЕМА С КЕШИРОВАНИЕМ**
|
||||
|
||||
**Симптом:** Данные не обновляются в реальном времени
|
||||
|
||||
**Диагностика:**
|
||||
|
||||
- Проверить политику кеширования Apollo Client
|
||||
- Убедиться, что `refetchAll()` вызывается после отправки
|
||||
|
||||
### **4. 🚫 ПРОБЛЕМА С БЕЗОПАСНОСТЬЮ/КОНТЕКСТОМ**
|
||||
|
||||
**Симптом:** Неправильный `currentUser` в контексте
|
||||
|
||||
**Диагностика:**
|
||||
|
||||
- Проверить, что JWT токен корректный
|
||||
- Убедиться, что контекст GraphQL правильно извлекает пользователя
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ **ПЛАН ДИАГНОСТИКИ**
|
||||
|
||||
### **ЭТАП 1: ПРОВЕРКА ЛОГОВ**
|
||||
|
||||
**✅ УЛУЧШЕННОЕ ЛОГИРОВАНИЕ ДОБАВЛЕНО:**
|
||||
|
||||
#### **Бэкенд (GraphQL резолверы):**
|
||||
|
||||
```typescript
|
||||
// При отправке заявки:
|
||||
console.warn('📩 SEND_COUNTERPARTY_REQUEST - ВЫЗВАН:', {
|
||||
receiverId: args.input.receiverId,
|
||||
requestType: args.input.requestType,
|
||||
hasMessage: !!args.input.message,
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
|
||||
// При успешной отправке:
|
||||
console.warn('✅ ЗАЯВКА НА ПАРТНЕРСТВО ОТПРАВЛЕНА:', {
|
||||
requestId: request.id,
|
||||
senderId: currentUser.organization.id,
|
||||
senderType: currentUser.organization.type,
|
||||
receiverId: args.input.receiverId,
|
||||
receiverType: receiverOrganization.type,
|
||||
})
|
||||
|
||||
// При загрузке входящих заявок:
|
||||
console.warn('📥 INCOMING_REQUESTS ДИАГНОСТИКА:', {
|
||||
userId: currentUser.id,
|
||||
organizationId: currentUser.organization.id,
|
||||
organizationType: currentUser.organization.type,
|
||||
requestsCount: incomingRequests.length,
|
||||
timestamp: new Date().toISOString(),
|
||||
requests: incomingRequests.map((r) => ({
|
||||
id: r.id,
|
||||
senderId: r.senderId,
|
||||
senderType: r.sender.type,
|
||||
status: r.status,
|
||||
createdAt: r.createdAt,
|
||||
})),
|
||||
})
|
||||
```
|
||||
|
||||
#### **Фронтенд (React hooks):**
|
||||
|
||||
```typescript
|
||||
// При успешной загрузке входящих заявок:
|
||||
console.warn('🎯 INCOMING_REQUESTS ФРОНТЕНД:', {
|
||||
requestsCount: data?.incomingRequests?.length || 0,
|
||||
requests:
|
||||
data?.incomingRequests?.map((r) => ({
|
||||
id: r.id,
|
||||
senderId: r.sender?.id,
|
||||
senderName: r.sender?.name || r.sender?.fullName,
|
||||
status: r.status,
|
||||
})) || [],
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
```
|
||||
|
||||
### **ЭТАП 2: ПРОВЕРКА БАЗЫ ДАННЫХ**
|
||||
|
||||
```sql
|
||||
-- Проверить существующие заявки
|
||||
SELECT * FROM counterparty_requests
|
||||
WHERE status = 'PENDING'
|
||||
ORDER BY createdAt DESC
|
||||
LIMIT 10;
|
||||
|
||||
-- Проверить конкретного пользователя
|
||||
SELECT cr.*,
|
||||
sender.name as sender_name,
|
||||
receiver.name as receiver_name
|
||||
FROM counterparty_requests cr
|
||||
JOIN organizations sender ON cr.senderId = sender.id
|
||||
JOIN organizations receiver ON cr.receiverId = receiver.id
|
||||
WHERE cr.receiverId = 'USER_ORG_ID';
|
||||
```
|
||||
|
||||
### **ЭТАП 3: ПРОВЕРКА СЕТИ/ЗАПРОСОВ**
|
||||
|
||||
1. Открыть DevTools → Network
|
||||
2. Выполнить действие отправки заявки
|
||||
3. Проверить GraphQL запрос `sendCounterpartyRequest`
|
||||
4. Проверить ответ сервера
|
||||
5. Перейти во входящие заявки
|
||||
6. Проверить GraphQL запрос `GetIncomingRequests`
|
||||
7. Проверить данные в ответе
|
||||
|
||||
---
|
||||
|
||||
## 🎯 **РЕКОМЕНДАЦИИ ДЛЯ ПОЛЬЗОВАТЕЛЯ**
|
||||
|
||||
### **НЕМЕДЛЕННЫЕ ДЕЙСТВИЯ:**
|
||||
|
||||
1. **Проверить браузерную консоль:**
|
||||
- Открыть DevTools (F12)
|
||||
- Перейти в Console
|
||||
- Искать сообщения с `📩 SEND_COUNTERPARTY_REQUEST` и `📥 INCOMING_REQUESTS`
|
||||
|
||||
2. **Проверить Network tab:**
|
||||
- Открыть DevTools → Network
|
||||
- Отправить заявку снова
|
||||
- Найти GraphQL запрос `sendCounterpartyRequest`
|
||||
- Проверить статус ответа (должен быть 200)
|
||||
- Проверить содержимое ответа
|
||||
|
||||
3. **Обновить страницу:**
|
||||
- Полностью перезагрузить страницу (Ctrl+F5)
|
||||
- Проверить входящие заявки снова
|
||||
|
||||
4. **Попробовать от другого пользователя:**
|
||||
- Войти как получатель заявки
|
||||
- Проверить раздел "Входящие заявки"
|
||||
|
||||
### **ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ НУЖНА:**
|
||||
|
||||
- **От кого и кому** отправлялась заявка (типы организаций)
|
||||
- **Есть ли ошибки** в браузерной консоли
|
||||
- **Статус ответа** GraphQL запроса
|
||||
- **Время отправки** заявки для поиска в логах
|
||||
|
||||
---
|
||||
|
||||
## 📋 **СЛЕДУЮЩИЕ ШАГИ**
|
||||
|
||||
1. **Получить логи от пользователя** (console + network)
|
||||
2. **Проверить базу данных** на наличие заявки
|
||||
3. **Воспроизвести проблему** в тестовой среде
|
||||
4. **Исправить найденную проблему**
|
||||
5. **Обновить документацию** с решением
|
||||
|
||||
---
|
||||
|
||||
**Диагностика начата:** 22:40, 2025-09-19
|
||||
**Статус:** 🔍 Ожидание дополнительной информации от пользователя
|
Reference in New Issue
Block a user