Объект результата

Объект результата в Vest представляет собой центральную структуру данных, формируемую после выполнения набора правил валидации. Он агрегирует информацию о состоянии проверки, деталях каждого теста, ошибках, предупреждениях и контексте выполнения. Вся модель работы библиотеки строится вокруг детерминированного формирования этого объекта, что позволяет использовать его как единый источник истины о состоянии валидируемых данных.

Базовый объект результата содержит несколько ключевых уровней информации:

  • агрегированное состояние валидности
  • детализированные результаты по полям
  • список ошибок и предупреждений
  • метаданные выполнения тестов
  • структурированное представление групп проверок

Типовая форма может быть представлена следующим образом:

{
  valid: false,
  errors: [],
  warnings: [],
  testResults: [],
  fieldResults: {
    username: {
      valid: false,
      errors: ["required", "minLength"],
      warnings: [],
      tests: [...]
    }
  }
}

Каждое из этих полей формируется на основе декларативно описанных правил и их последовательного выполнения.

Флаг общей валидности

Поле valid является агрегированным индикатором состояния всей схемы валидации. Оно вычисляется на основании результатов всех тестов:

  • значение true означает отсутствие ошибок во всех проверках
  • значение false означает наличие хотя бы одной ошибки уровня ошибки (error severity)

Важно, что предупреждения не влияют на итоговое значение валидности. Это позволяет разделять критические и некритические нарушения правил.

Структура ошибок

Поле errors представляет собой глобальный список всех ошибок, обнаруженных при выполнении тестов. В зависимости от конфигурации оно может быть:

  • плоским массивом строк
  • либо структурированным объектом, сгруппированным по полям

Пример агрегированного списка:

errors: [
  { field: "email", rule: "required" },
  { field: "password", rule: "minLength" }
]

Локализованная форма:

errors: {
  email: ["required"],
  password: ["minLength"]
}

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

Предупреждения как отдельный уровень результата

Поле warnings повторяет концепцию ошибок, но относится к нефатальным отклонениям. Эти данные используются для:

  • отображения рекомендаций пользователю
  • аналитических проверок качества данных
  • мягких ограничений бизнес-логики

Предупреждения не влияют на valid, но полностью сохраняются в объекте результата, что позволяет использовать их независимо от основного потока логики.

Детализация по полям

Одним из ключевых элементов структуры является fieldResults. Это нормализованное представление состояния каждого поля формы или объекта данных.

Каждое поле содержит:

  • valid — локальная валидность
  • errors — список нарушенных правил
  • warnings — список предупреждений
  • tests — результат каждого выполненного теста

Пример:

fieldResults: {
  email: {
    valid: false,
    errors: ["format", "required"],
    warnings: ["weakDomain"],
    tests: [
      { name: "required", pass: false },
      { name: "format", pass: false },
      { name: "weakDomain", pass: true }
    ]
  }
}

Такая структура позволяет точно определить, какое правило и на каком этапе привело к итоговому состоянию поля.

Результаты тестов

Поле testResults содержит полную историю выполнения всех проверок без группировки по полям. Это низкоуровневое представление, используемое для:

  • отладки логики валидации
  • построения кастомных репортов
  • трассировки выполнения правил

Каждый элемент массива обычно включает:

  • имя теста
  • целевое поле
  • результат выполнения
  • время или порядок выполнения
  • дополнительный контекст

Пример:

testResults: [
  {
    field: "email",
    test: "format",
    pass: false,
    message: "Invalid email format"
  }
]

Связь между уровнями представления

Объект результата формируется по иерархическому принципу:

  1. Выполняются отдельные тесты
  2. Результаты агрегируются в testResults
  3. Данные группируются по полям в fieldResults
  4. Производится вычисление глобальных errors и warnings
  5. Формируется итоговый флаг valid

Такой подход обеспечивает согласованность данных на всех уровнях абстракции и исключает расхождения между агрегированным и детализированным состоянием.

Инварианты объекта результата

Структура результата в Vest подчиняется ряду строгих правил:

  • наличие хотя бы одного источника истины для каждого уровня данных
  • детерминированность формирования результата при одинаковых входных данных
  • неизменяемость результата после генерации
  • согласованность между fieldResults и глобальными списками ошибок

Особое значение имеет неизменяемость: объект результата рассматривается как снимок состояния, а не как динамическая структура.

Использование нормализованных данных

Нормализация внутри объекта результата позволяет эффективно работать с ним в интерфейсных слоях:

  • быстрое отображение ошибок по полям без дополнительной фильтрации
  • построение индикаторов состояния формы
  • реализация реактивных обновлений интерфейса
  • кэширование результатов без пересчёта логики

Структура fieldResults особенно важна для UI-ориентированных сценариев, где требуется мгновенный доступ к состоянию конкретного поля без обхода всего дерева проверок.

Семантика вложенных результатов

В случаях, когда проверяемый объект имеет вложенную структуру, результат также может принимать иерархический вид. Поля могут содержать подструктуры:

fieldResults: {
  user: {
    email: {
      valid: false,
      errors: ["required"]
    }
  }
}

Такая модель позволяет работать с глубоко вложенными схемами без потери точности диагностики.

Согласованность состояния и тестов

Каждый элемент fieldResults всегда может быть восстановлен из testResults. Это обеспечивает:

  • возможность повторной агрегации результата
  • независимость визуального слоя от внутренней структуры
  • упрощение тестирования самой системы валидации

При этом testResults выступает первичным источником, а остальные структуры являются производными.

Роль объекта результата в архитектуре

Объект результата в Vest является связующим звеном между декларативными правилами валидации и прикладной логикой приложения. Он отделяет описание проверок от их интерпретации, предоставляя унифицированный формат, пригодный для:

  • логики бизнес-правил
  • пользовательского интерфейса
  • серверной обработки данных
  • тестирования и отладки

Строгая структура и предсказуемость формирования делают его устойчивым к изменению количества правил, сложности схем и глубины вложенности данных.