Добавлено логирование для отладки черновиков
- Добавлены логи в frontend (ClaimForm.tsx) для отслеживания unified_id и запросов к API - Добавлены логи в backend (claims.py) для отладки SQL запросов - Создан лог сессии с описанием проблемы и текущего состояния - Проблема: API возвращает 0 черновиков, хотя в БД есть данные
This commit is contained in:
183
docs/DATABASE_SCHEMA.md
Normal file
183
docs/DATABASE_SCHEMA.md
Normal file
@@ -0,0 +1,183 @@
|
||||
# Схема базы данных clpr_*
|
||||
|
||||
## Основные таблицы
|
||||
|
||||
### 1. `clpr_users` - Основная таблица пользователей
|
||||
```
|
||||
id (integer, PK)
|
||||
universal_id (uuid)
|
||||
unified_id (varchar) ← КЛЮЧЕВОЕ ПОЛЕ для связи
|
||||
phone (varchar)
|
||||
created_at, updated_at
|
||||
```
|
||||
|
||||
### 2. `clpr_user_accounts` - Связь пользователей с каналами
|
||||
```
|
||||
id (integer, PK)
|
||||
user_id (integer) → FK на clpr_users.id
|
||||
channel (text) - 'telegram', 'web_form'
|
||||
channel_user_id (text) - ID в канале (telegram_id для telegram, phone для web_form)
|
||||
```
|
||||
|
||||
**Связь:**
|
||||
- `clpr_user_accounts.user_id` → `clpr_users.id`
|
||||
- Уникальность: `(channel, channel_user_id)` - один пользователь может быть в нескольких каналах
|
||||
|
||||
### 3. `clpr_claims` - Заявки/черновики
|
||||
```
|
||||
id (uuid, PK)
|
||||
session_token (varchar)
|
||||
unified_id (varchar) ← СВЯЗЬ С clpr_users.unified_id (должен заполняться n8n!)
|
||||
telegram_id (bigint)
|
||||
channel (text) - 'telegram', 'web_form'
|
||||
user_id (integer) - возможно FK на clpr_users.id
|
||||
type_code (text)
|
||||
status_code (text) - 'draft', 'in_work', etc.
|
||||
policy_number (text)
|
||||
payload (jsonb) - содержит phone, claim_id, wizard_plan, answers, documents_meta и т.д.
|
||||
is_confirmed (boolean)
|
||||
created_at, updated_at, expires_at
|
||||
```
|
||||
|
||||
**Связь:**
|
||||
- `clpr_claims.unified_id` → `clpr_users.unified_id` (логическая связь)
|
||||
- `clpr_claims.user_id` → `clpr_users.id` (возможно, не всегда заполнено)
|
||||
|
||||
### 4. `clpr_users_tg` - Данные Telegram пользователей
|
||||
```
|
||||
telegram_id (bigint, PK)
|
||||
unified_id (varchar) → clpr_users.unified_id
|
||||
phone_number (varchar)
|
||||
first_name_tg, last_name_tg, username, language_code, is_premium
|
||||
first_name, last_name, middle_name, birth_date, etc.
|
||||
```
|
||||
|
||||
### 5. `clpr_claim_documents` - Документы заявок
|
||||
```
|
||||
id (uuid, PK)
|
||||
claim_id (varchar) → clpr_claims.id (логическая связь через payload->>'claim_id')
|
||||
field_name (text)
|
||||
file_id (text)
|
||||
uploaded_at (timestamp)
|
||||
file_name, original_file_name
|
||||
```
|
||||
|
||||
### 6. `clpr_documents` - Хранилище документов
|
||||
```
|
||||
id (uuid, PK)
|
||||
source (text)
|
||||
content (text)
|
||||
metadata (jsonb)
|
||||
created_at
|
||||
```
|
||||
|
||||
## Логика работы с черновиками для web_form
|
||||
|
||||
### Шаг 1: Проверка пользователя в CRM
|
||||
- n8n вызывает `CreateWebContact` с phone
|
||||
- Получает `contact_id` из CRM
|
||||
|
||||
### Шаг 2: Поиск/создание пользователя в PostgreSQL
|
||||
SQL запрос (аналогично Telegram):
|
||||
```sql
|
||||
WITH existing AS (
|
||||
SELECT u.id AS user_id, u.unified_id
|
||||
FROM clpr_user_accounts ua
|
||||
JOIN clpr_users u ON u.id = ua.user_id
|
||||
WHERE ua.channel = 'web_form'
|
||||
AND ua.channel_user_id = '{phone}'
|
||||
LIMIT 1
|
||||
),
|
||||
create_user AS (
|
||||
INSERT INTO clpr_users (unified_id, phone, created_at, updated_at)
|
||||
SELECT 'usr_' || gen_random_uuid()::text, '{phone}', now(), now()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM existing)
|
||||
RETURNING id AS user_id, unified_id
|
||||
),
|
||||
final_user AS (
|
||||
SELECT * FROM existing
|
||||
UNION ALL
|
||||
SELECT * FROM create_user
|
||||
),
|
||||
create_account AS (
|
||||
INSERT INTO clpr_user_accounts(user_id, channel, channel_user_id)
|
||||
SELECT
|
||||
(SELECT user_id FROM final_user),
|
||||
'web_form',
|
||||
'{phone}'
|
||||
ON CONFLICT (channel, channel_user_id) DO NOTHING
|
||||
)
|
||||
SELECT unified_id FROM final_user LIMIT 1;
|
||||
```
|
||||
|
||||
### Шаг 3: Создание/обновление заявки
|
||||
- n8n создает/обновляет запись в `clpr_claims`
|
||||
- **ВАЖНО:** заполняет `unified_id` из результата шага 2
|
||||
- Сохраняет `phone` в `payload->>'phone'`
|
||||
- `channel = 'web_form'`
|
||||
- `status_code = 'draft'` для черновиков
|
||||
|
||||
### Шаг 4: Поиск черновиков
|
||||
```sql
|
||||
SELECT
|
||||
c.id,
|
||||
c.payload->>'claim_id' as claim_id,
|
||||
c.session_token,
|
||||
c.status_code,
|
||||
c.payload,
|
||||
c.created_at,
|
||||
c.updated_at
|
||||
FROM clpr_claims c
|
||||
WHERE c.status_code = 'draft'
|
||||
AND c.channel = 'web_form'
|
||||
AND c.unified_id = '{unified_id}' -- ← ПОИСК ПО unified_id!
|
||||
ORDER BY c.updated_at DESC
|
||||
LIMIT 20;
|
||||
```
|
||||
|
||||
## Проблема в текущей реализации
|
||||
|
||||
**Текущее состояние:**
|
||||
- В `clpr_claims` поле `unified_id` **ПУСТОЕ** для всех черновиков web_form
|
||||
- Поиск идет по `payload->>'phone'` или `session_token`, что не надежно
|
||||
|
||||
**Решение:**
|
||||
- n8n должен заполнять `unified_id` при создании/обновлении заявки
|
||||
- Backend должен искать черновики по `unified_id`, а не по phone/session_id
|
||||
|
||||
## Связи между таблицами
|
||||
|
||||
```
|
||||
clpr_users (unified_id)
|
||||
↑
|
||||
| (через unified_id)
|
||||
|
|
||||
clpr_claims (unified_id)
|
||||
|
|
||||
| (через user_id)
|
||||
↓
|
||||
clpr_user_accounts (user_id → clpr_users.id)
|
||||
|
|
||||
| (channel='web_form', channel_user_id=phone)
|
||||
↓
|
||||
clpr_claims (payload->>'phone')
|
||||
```
|
||||
|
||||
## Для Telegram (для сравнения)
|
||||
|
||||
```
|
||||
clpr_users (unified_id)
|
||||
↑
|
||||
| (через unified_id)
|
||||
|
|
||||
clpr_users_tg (unified_id)
|
||||
|
|
||||
| (telegram_id)
|
||||
↓
|
||||
clpr_user_accounts (channel='telegram', channel_user_id=telegram_id)
|
||||
|
|
||||
| (user_id)
|
||||
↓
|
||||
clpr_users (id)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user