Перейти к основному содержимому

Модели ответа dev-stats (типизированные ряды / точки / сводки)

Дом общих строительных блоков типизированных ответов области developers (ADR-0057): value objects, ref-модели и примитивы рядов/точек, переиспользуемые методами. Модель ответа каждого метода (её поля) описана в документе самого метода — здесь только разделяемые типы и карта «метод → модель». Все модели строго типизированы. Пагинируемые рейтинги возвращают страницу (items/totalCount/page/pageSize/ hasMore).

Value objects

NullableRange<T>

Диапазон с опциональными границами (From/To) — вместо парных скалярных *From/*Max/*Min/*To полей. Одна модель, одна валидация From <= To.

ПолеТипОписание
FromT?нижняя граница (включительно)
ToT?верхняя граница (исключительно для бинов; null — открытый хвост)

Применение: период фильтра NullableRange<DateOnly> (dev-stats-filter.md); бины гистограммы длительностей NullableRange<int> (get-duration-histogramDurationBinModel.Range); бакеты частоты повторов NullableRange<int> (get-repeat-frequencyRepeatBucketModel.Range).

Семантика границ зависит от применения (единый тип — разные соглашения о включении):

ПрименениеFromToОткрытый хвост
Период дат (DateOnly)включительновключительно (день To входит в выборку)обе границы обязательны (период — required-поле фильтра)
Бины длительности/повторов (int)включительноисключительно ([From; To))последний бин To = null — «From и больше»

Общее правило валидности во всех применениях: если обе границы заданы — From <= To; для наборов бинов диапазоны идут без перекрытий и без разрывов, покрывая всю ось (первый бин от 0, последний — открытый).

Страница рейтинга

Единый формат страницы для пагинируемых рейтингов (top-objects, bounce-signal, time-to-first-view). Параметры пагинации (page/pageSize) — dev-stats-filter.md, method-specific.

ПолеТипОписание
ItemsT[]строки текущей страницы, отсортированные по мере уровня (по умолчанию по убыванию)
TotalCountlongобщее число групп уровня по срезу (для счётчика/пейджера)
Pageintномер запрошенной страницы (с 1)
PageSizeintразмер страницы (≤ 100; см. валидацию пагинации)
HasMoreboolесть ли следующая страница (Page · PageSize < TotalCount)

Правила: страница за пределом последней (Page больше числа страниц) — валидный 200 с пустым Items и прежним TotalCount (не ошибка). Сортировка при равенстве меры доопределяется стабильным вторичным ключом (id узла) — порядок между вызовами одной страницы детерминирован.

TimeSeriesPointModel

Базовая точка временного ряда (наследуется/переиспользуется рядами trend/unique-viewers).

ПолеТипОписание
Datestring (ISO date)начало бакета (day/toMonday/toStartOfMonth)
Viewslongпросмотры бакета (uniqMerge)
UniqViewerslongуникальные зрители бакета

Ref-модели узлов иерархии

Пара «id + имя» узла иерархии выносится во вложенную ref-модель (а не двумя плоскими полями). Имя резолвится из реплик-измерений dim_* (../dimensions/); при лаге измерения Name — пустой/last-known (деградация подписи, не ошибка).

МодельПоляИсточник имени
DeveloperRefModelDeveloperId: Guid, DeveloperName: stringdim_developer
ProjectRefModelProjectId: Guid, ProjectName: stringdim_project
BuildingRefModelBuildingId: Guid, BuildingName: stringdim_building
LayoutGroupRefModelLayoutGroupId: Guid, LayoutGroupName: stringdim_layout_group
LayoutRefModelLayoutId: Guid, LayoutName: stringdim_layout
PropertyObjectRefModelPropertyObjectId: Guid, PropertyObjectNumber: stringdim_property_object

Узлы в get-hierarchy-funnel (HierarchyStageModel/ HierarchyNodeModel) и get-top-objects (TopObjectRow) несут соответствующую ref-модель уровня вместо разрозненных id/name.

PropertyObjectLayoutModel (группа связанных полей планировки)

Связанные атрибуты планировки объекта недвижимости — одной под-моделью (а не набором плоских полей).

ПолеТипИсточник
LayoutIdGuid?dim_property_object.LayoutId
LayoutGroupIdGuid?dim_property_object.LayoutGroupId
LayoutNamestringdim_layout.Name
Roomsintdim_layout.Rooms (0 = студия)
TotalAreaM2decimaldim_layout.TotalArea

Карта «метод → result-модель» (поля — в документе метода)

МетодResult-модельКлючевые под-модели
get-views-summaryViewsSummaryResultViewerKindSummaryModel
get-views-trendViewsTrendResultViewsTrendPointModel, ViewsTrendComparisonModel
get-unique-viewersUniqueViewersResultViewerKindCountModel, UniqueViewersPointModel
get-duration-histogramDurationHistogramResultDurationBinModel (NullableRange<int>)
get-repeat-frequencyRepeatFrequencyResultRepeatBucketModel (NullableRange<int>)
get-hierarchy-funnelHierarchyFunnelResultHierarchyStageModel, HierarchyNodeModel (ref-модели)
get-conversion-funnelConversionFunnelResultConversionStageModel
get-top-objectsстраница TopObjectRowTopObjectRow (ref-модель уровня)
get-session-depthSessionDepthResultSessionDepthBucketModel, SessionDepthByViewerKindModel
get-activity-heatmapActivityHeatmapResultHeatmapCellModel
get-bounce-signalBounceSignalResultBounceOverallModel, PropertyObjectBounceModel
get-time-to-first-viewTimeToFirstViewResultTtfvOverallModel, PropertyObjectTtfvModel

Экспорт-отчёт (DevStatsReportRowModel/DevStatsReportTotalsModel) — reports/dev-stats-export.md.

Инварианты моделей ответа

КодИнвариантСмысл
INV-RM-1 AggregateOnlyЛюбая модель ответа несёт только агрегаты и сегменты (счётчики, доли, длительности, ViewerKind/ViewSource) — без UserId/AnonymousId/SessionId/ФИО/контактовPII зрителей не выходит наружу (ADR-0057 §6)
INV-RM-2 RefPairConsistencyВ ref-модели id — обязателен и всегда заполнен; Name/Number — из dim_* и может быть пустым/last-known при лаге измеренияМетрика не блокируется отсутствием подписи; клиент рисует id, подпись догоняет
INV-RM-3 NullMeansNoBaseПроизводные (конверсии, Δ%, средние на пустом знаменателе) при нулевом знаменателе → null, не 0 и не ошибкаОтличие «нет базы/нового» от «ноль»; нет деления на ноль
INV-RM-4 UniqNotSummableUniqViewers/уникальные счётчики агрегируются пересчётом из состояний, а не суммой строк-детейСумма уникальных по узлам ≥ уникальных по родителю — родительский показатель не задваивается

Совместимость и маскирование

  • Additive: новое опциональное поле модели/новая под-модель — совместимо; клиент-визуализатор игнорирует неизвестные поля. Удаление/переименование/смена типа поля — breaking (согласовать с потребителем).
  • Новое wire-значение enum (ViewerKind/ViewSource) в ответе — breaking для визуализатора (см. viewer-classification.md, «Совместимость»).
  • Маскирование: DeveloperId в презентационных выгрузках маскируется; в API-ответах наружу отдаются только агрегаты — маскировать нечего (персональные идентификаторы в модель не попадают, INV-RM-1).

Обратные ссылки

Автоссылки: где используется этот документ.

Связанные документы