Files
crm.clientright.ru/ticket_form/docs/DATABASE_SCHEMA.md
Fedor 52fe013375 feat(ticket_form): unified_id/contact_id передача, исправлен мерж сессии, новая сессия для жалобы
- Добавлены unified_id и contact_id в TicketFormDescriptionRequest
- Исправлен CODE_MERGE_PROJECT_TO_SESSION.js - теперь сохраняются ВСЕ данные из body.other
- Добавлен fallback на получение other из Webhook напрямую
- Генерация новой session_id при создании новой жалобы (сохраняя авторизацию)
- Добавлен SQL_SELECT_CONTACT_WITH_CUSTOM_FIELDS.sql для CRM контактов
- Создан SESSION_LOG_2025-11-25.md с документацией сессии
2025-11-25 20:02:21 +03:00

5.3 KiB
Raw Blame History

Схема базы данных 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_idclpr_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_idclpr_users.unified_id (логическая связь)
  • clpr_claims.user_idclpr_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):

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: Поиск черновиков

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)