# User Tracing в Scenario

## Описание

В класс Scenario добавлена поддержка трассировки действий пользователей для отладки и мониторинга выполнения диалогов и действий.

## Основные возможности

- Трассировка всех событий обработки запросов пользователей
- Отслеживание выполнения действий, диалогов, switch-операций
- Форматирование больших объектов для предотвращения переполнения логов
- Защита от утечек памяти с помощью `finally` блока
- Селективная трассировка только для указанных пользователей

## События трассировки

### Запросы

- `request_received` - получен запрос от пользователя
- `request_complete` - обработка запроса завершена

### Диалоги

- `dialog_matched` - найден подходящий диалог
- `dialog_complete` - диалог выполнен
- `dialog_not_found` - диалог не найден
- `dialog_error` - ошибка при выполнении диалога

### Действия

- `action_start` - начало выполнения действия
- `action_result` - результат выполнения действия
- `action_branch` - переход по условной ветке (true/false)
- `action_error` - ошибка при выполнении действия
- `action_error_caught` - ошибка перехвачена и обработана
- `action_not_defined` - действие не определено

### doDialog

- `do_dialog` - переход к другому диалогу
- `do_dialog_return` - возврат из диалога

### doSwitch

- `switch_start` - начало обработки switch
- `switch_case_matched` - найден подходящий case
- `switch_default` - выполнение default ветки
- `switch_no_match` - не найдено совпадений

## Интерфейс UserTracing Service

Сервис трассировки должен реализовывать следующий интерфейс:

```javascript
class UserTracingService {
  /**
   * Проверить, включена ли трассировка для пользователя
   * @param {string|number} userId - ID пользователя
   * @returns {boolean}
   */
  isTracing(userId) {}

  /**
   * Записать событие трассировки
   * @param {string|number} userId - ID пользователя
   * @param {string} event - Название события
   * @param {Object} data - Данные события
   */
  trace(userId, event, data) {}
}
```

## Использование

### Базовое использование

```javascript
import { Scenario } from 'vvlad1973-telegram-framework';

const scenario = new Scenario(logger);

// Инжектировать сервис трассировки
scenario.userTracing = myTracingService;

// Загрузить диалоги и обрабатывать запросы как обычно
await scenario.loadDialogs(['dialogs.jsonc']);
await scenario.process(request, user, context);
```

### Пример реализации сервиса трассировки

```javascript
class SimpleTracingService {
  constructor() {
    this.traces = new Map();
    this.trackedUsers = new Set();
  }

  isTracing(userId) {
    return this.trackedUsers.has(userId);
  }

  trace(userId, event, data) {
    if (!this.traces.has(userId)) {
      this.traces.set(userId, []);
    }

    this.traces.get(userId).push({
      timestamp: new Date().toISOString(),
      event,
      data,
    });
  }

  enableTracing(userId) {
    this.trackedUsers.add(userId);
  }

  disableTracing(userId) {
    this.trackedUsers.delete(userId);
  }

  getTraces(userId) {
    return this.traces.get(userId) || [];
  }

  clear() {
    this.traces.clear();
  }
}

// Использование
const tracingService = new SimpleTracingService();
scenario.userTracing = tracingService;

// Включить трассировку для пользователя
tracingService.enableTracing(12345);

// После обработки запросов
const traces = tracingService.getTraces(12345);
console.log(traces);
```

## Форматирование данных

Метод `#formatValue()` автоматически форматирует данные для предотвращения переполнения логов:

- Строки > 200 символов обрезаются с превью
- Массивы > 5 элементов показываются как `{_type: 'array', _len: N}`
- Объекты > 10 ключей показываются как `{_type: 'object', _keys: [...]}`
- `undefined` преобразуется в `{_type: 'undefined'}`

## Защита от утечек памяти

Контекст трассировки для каждого запроса хранится в приватном `Map` и гарантированно очищается в `finally` блоке метода `process()`, даже если произошла ошибка.

## Обратная совместимость

Все изменения полностью обратно совместимы:

- Свойство `userTracing` по умолчанию `null`
- Если трассировка не инжектирована, код работает без изменений
- Не требуется изменение существующего кода

## Производительность

- Проверка `userTracing?.isTracing(userId)` выполняется перед форматированием данных
- Минимальное влияние на производительность когда трассировка отключена
- Форматирование данных выполняется только для трассируемых пользователей

## Тестирование

Полный набор тестов доступен в `tests/scenario-tracing.test.js`:

```bash
npm test                  # Запустить все тесты
npm run test:watch        # Запустить тесты в watch режиме
npm run test:coverage     # Запустить с покрытием кода
```

Тесты покрывают:

- Очистку контекста после успешного выполнения
- Очистку контекста после ошибок
- Корректность событий трассировки
- Работу без сервиса трассировки
- Селективную трассировку пользователей
- Трассировку doDialog и doSwitch
- Форматирование больших строк
