
КРИТИЧЕСКИЕ ИСПРАВЛЕНИЯ: - Исправлено отображение входящих заявок (неправильное извлечение данных) - Устранен 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>
348 lines
11 KiB
Markdown
348 lines
11 KiB
Markdown
# 🔍 ДИАГНОСТИКА: ПРОБЛЕМА С ВХОДЯЩИМИ ЗАЯВКАМИ НА ПАРТНЕРСТВО
|
||
|
||
> **Дата:** 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
|
||
**Статус:** 🔍 Ожидание дополнительной информации от пользователя
|