# Event taxonomy: как построить tracking plan без мусора

> Проектируем event taxonomy от бизнес-вопросов до проверяемых payloads: naming, properties, identity, privacy, versioning, QA и AI без выдумок.
> Author: Roman Belov · Published: 2026-04-01 · Source: https://futurecraft.pro/ru/blog/event-taxonomy-ai/

Самый быстрый способ испортить продуктовую аналитику — инструментировать каждый экран.

Событий много, dashboards строятся, но никто не уверен, что означают цифры. `Subscription Created` может срабатывать при открытии checkout, успешной оплате или появлении строки в базе. Во всех случаях имя выглядит аккуратно, а metric означает разное.

Event taxonomy решает проблему языка. Tracking plan — проблему реализации. AI помогает подготовить оба документа, но сначала команда должна решить, какие вопросы важны и какая система владеет каждым фактом.

## Taxonomy и tracking plan — разные документы

Актуальный гайд Amplitude проводит полезную границу: taxonomy определяет, **как называть сущности**, а tracking plan — **что собирать**, включая firing conditions и properties ([Amplitude](https://amplitude.com/taxonomy-generator)).

Сохраните это разделение в документации:

### Taxonomy

- паттерн имён событий;
- паттерн имён properties;
- словарь общих понятий;
- типы данных и единицы;
- правила identity, time и versions;
- deprecation policy.

### Tracking plan

- поддерживаемый бизнес-вопрос и metric;
- имя события и точное определение;
- producer и source of truth;
- trigger и exclusions;
- контракт properties;
- privacy classification;
- owner и lifecycle status;
- требования к тестам и мониторингу.

Имя `Invoice Paid` относится к taxonomy. Формулировка «срабатывает один раз на сервере после подтверждения settlement платёжным провайдером; повторная доставка использует тот же event ID» относится к tracking plan.

## Шаг 1. Начните с решений, а не экранов

В руководстве Twilio Segment сначала определяется, что команда хочет узнать, и только затем вопросы связываются с events и properties. Такой порядок не даёт инструментированию превратиться в каталог UI controls ([Segment](https://app-canary.segment.com/academy/collecting-data/how-to-create-a-tracking-plan/)).

До именования событий составьте decision table:

| Решение | Вопрос | Metric или analysis | Нужные evidence |
|---|---|---|---|
| Улучшить onboarding | Где подходящие accounts останавливаются до first value? | step conversion по account cohort | account created, обязательные steps, value event |
| Изменить trial | Какие accounts конвертируются после meaningful use? | conversion по заранее заданному activation behavior | trial eligibility, activation evidence, paid conversion |
| Исправить collaboration | Становятся ли приглашённые коллеги active members? | invite-to-activation funnel | invite sent, invite accepted, core action |

Здесь становятся видны расплывчатые metrics. Activation не является событием, пока product team не определила behavior, actor, time window и активируемую сущность. В B2B единицей часто служит account, а не человек. Зафиксируйте определение рядом с [North Star metric](/ru/blog/north-star-metric/) и retention model, а не прячьте в SDK call.

Если событие не поддерживает текущее решение или analysis, не добавляйте его в первый release. Evidence можно собрать позже. Исторические данные, смысл которых никто не может объяснить, не становятся активом.

## Шаг 2. Определите grain события и source of truth

До выбора имени закончите фразу:

> Одна строка означает один ___, выполненный ___ над ___ в момент ___.

Например:

```text
Одна строка Invoice Paid означает один оплаченный invoice,
принадлежащий одному workspace, подтверждённый billing service,
во время settlement у provider.
```

Затем определите:

- **actor:** anonymous device, user, service или admin;
- **subject:** account, project, invoice, document или другая сущность;
- **grain:** один click, attempt, state transition или business transaction;
- **producer:** web client, mobile client, backend service, webhook processor;
- **source of truth:** система, имеющая право утверждать факт;
- **event time:** момент действия, а не только приёма данных vendor;
- **deduplication key:** стабильный ID для retries, если pipeline его поддерживает.

Client-side event уместен для взаимодействия, наблюдаемого только клиентом, например показа panel. Billing, permissions, успешные jobs и другие authoritative state transitions обычно надёжнее отправлять с server side. Если обе стороны фиксируют связанные сигналы, разведите смысл: `Checkout Submitted` от клиента и `Invoice Paid` от billing service.

Не разрешайте двум producers отправлять одно имя с разной семантикой. Dashboard не исправит это задним числом.

## Шаг 3. Выберите одну naming grammar

`Object Action` в past tense легко читать:

```text
Account Created
Invite Accepted
Report Exported
```

Lowercase snake_case удобен в коде и warehouse:

```text
account_created
invite_accepted
report_exported
```

Оба варианта допустимы при стабильном смысле. Даже first-party рекомендации различаются: Amplitude показывает object-plus-action в Title Case или snake_case, а PostHog публиковал convention с lowercase snake_case. Поддержка формата платформой не делает его обязательным.

Рабочие правила:

1. Выберите единый регистр и tense для custom events.
2. Используйте язык предметной области, а не подписи buttons.
3. Описывайте наблюдаемый завершённый факт, а не желаемый результат.
4. Выносите вариации в properties, если смысл события один.
5. Зарезервируйте vendor-defined names и prefixes.
6. Никогда не собирайте event name динамически.

`Report Exported` с `format: "csv"` проще поддерживать, чем `CSV Report Exported`, `PDF Report Exported` и новое событие для каждого формата. Но разные факты не стоит сжимать в бессодержательное `Action Completed`.

Properties требуют той же дисциплины:

```text
workspace_id       string
billing_interval   enum: monthly | annual
amount_minor       integer
currency           ISO 4217 string
is_first_invoice   boolean
occurred_at        RFC 3339 timestamp
```

Документируйте units. `amount: 99` бесполезно, пока plan не объясняет, это cents, dollars или другая currency.

## Шаг 4. Опишите настоящий event contract

Строка tracking plan должна давать developer, analyst и reviewer одно толкование.

| Поле | Пример |
|---|---|
| Event | `invoice_paid` |
| Purpose | Revenue и trial-conversion analysis |
| Definition | Billing provider подтвердил settlement |
| Fires | Один раз на settled invoice |
| Does not fire | Checkout открыт, payment pending, получен retry |
| Producer | `billing-webhook` |
| Subject | workspace |
| Event ID | provider invoice ID + settlement transition |
| Required properties | `workspace_id`, `invoice_id`, `amount_minor`, `currency`, `plan_id` |
| Optional properties | `coupon_id` |
| Owner | Billing engineering |
| Privacy | pseudonymous account data; без free text |
| Status | proposed / implemented / verified / deprecated |

Отделяйте event properties от изменяемых profile или entity properties. Сумма invoice на момент платежа относится к событию. Текущий план workspace может находиться в account profile, но изменяемое значение не должно переписывать исторический смысл.

Не добавляйте без privacy и cardinality review универсальные free-text поля: `feedback_text`, URL с query string, search query, имя документа или raw error. В них часто попадают secrets и personal data, а число значений растёт без контроля.

## Шаг 5. Спроектируйте identity до воронок

Ошибки identity создают вымышленных пользователей, разорванные funnels и утечки между accounts.

Зафиксируйте:

- создание и rotation anonymous identifier;
- момент назначения известного `user_id`;
- правила merge anonymous и known профиля;
- logout и shared-device behavior;
- account или group identity;
- membership пользователя в нескольких accounts;
- deletion и suppression flow;
- согласованность server и client.

Не считайте, что SDK автоматически реализует нужную продукту модель. У Amplitude, Mixpanel, PostHog, Segment и warehouse-first pipeline разные identity models и reserved fields. Сохраните одну conceptual model и добавьте mapping для каждой destination.

Постоянный `user_id` не становится анонимным только потому, что в нём нет email. ICO отмечает, что pseudonymised data может быть повторно связана с человеком через отдельно хранимую информацию. Для пользователей из ЕС применяются, среди прочего, purpose limitation, data minimisation, storage limitation и accountability ([European Commission](https://commission.europa.eu/law/law-topic/data-protection/information-business-and-organisations/principles-gdpr_en), [ICO](https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/data-sharing/anonymisation/pseudonymisation/)).

Для каждой property запишите:

```text
purpose | legal basis/approval | classification | destinations |
retention | deletion path | access group
```

Требования зависят от юрисдикции и данных — нужна проверка privacy или legal specialist. Строка в taxonomy не создаёт legal basis.

## Шаг 6. Ограничьте AI переданными evidence

Опасный prompt: «Сгенерируй 30 событий для моего SaaS». Он оптимизирует полноту таблицы, а не качество данных. Модель не знает ваши решения, реализацию, privacy obligations и event grain.

Передайте ограниченный набор inputs:

```text
Ты готовишь tracking plan только из переданных evidence.

Inputs:
- утверждённые бизнес-вопросы и metric definitions
- user journeys и state-transition diagrams
- экспорт существующих событий
- релевантные API contracts и code locations
- taxonomy rules
- privacy classification rules

Для каждого события:
1. Укажи бизнес-вопрос и input, требующий это событие.
2. Определи actor, subject, grain, trigger, exclusions, producer,
   source of truth, event time и deduplication behavior.
3. Перечисли required и optional properties: type, unit,
   allowed values, nullability и privacy class.
4. Сопоставь duplicates и legacy events.
5. Пиши UNKNOWN для недостающих фактов.
6. Отмечай high-cardinality, free-text, identity и PII risks.

Не выдумывай:
- activation definitions
- implementation locations
- legal bases
- retention periods
- thresholds
- vendor capabilities
```

Quality gate — это human review, schema validation и test payloads. Вторая LLM помогает найти несоответствия, но согласие двух моделей не доказывает связь с продуктом.

## Шаг 7. Сократите plan до первого полезного slice

Project-management product не нужен универсальный список из 30 событий в первый день. Допустим, текущие вопросы относятся к account activation и совместной работе. Первый slice может выглядеть так:

| Event | Producer | Зачем нужен | Key properties |
|---|---|---|---|
| `account_created` | backend | denominator для cohort | `account_id`, `created_by_user_id`, `signup_source` |
| `onboarding_step_completed` | backend или trusted client | step funnel | `account_id`, `step_id`, `flow_version` |
| `project_created` | backend | первое setup behavior | `account_id`, `project_id`, `creation_method` |
| `task_created` | backend | создан core object | `account_id`, `project_id`, `task_id` |
| `task_completed` | backend | завершена core work | `account_id`, `project_id`, `task_id` |
| `invite_sent` | backend | начало collaboration funnel | `account_id`, `invite_id`, `role` |
| `invite_accepted` | backend | следующий шаг collaboration | `account_id`, `invite_id`, `user_id` |
| `subscription_started` | billing service | paid conversion | `account_id`, `subscription_id`, `plan_id`, `currency` |

Это тоже draft. Account activation лучше рассчитывать из базовых фактов, а не отправлять как `First Value Moment Reached`. Derived metric можно изменить без просьбы к приложению угадать, когда появился value.

До добавления событий «return» и «reactivation» свяжите данные с объявленной [retention analysis](/ru/blog/retention-curve-pmf/). Sessions полезны для отдельных вопросов, но сами по себе не определяют retention.

## Шаг 8. Проверяйте до и после release

Таблица, однажды прошедшая review, начнёт расходиться с кодом. Ставьте проверки рядом с producers.

### До merge

- schema file или generated typed wrapper обновлён;
- event owner одобрил semantic change;
- required и forbidden properties покрыты тестами;
- representative payload не содержит raw PII и secrets;
- поведение duplicates и retries проверено;
- старые consumers найдены;
- изменение записано в changelog.

### В staging

Смотрите raw payload в collector, а не только финальный chart. Проверьте одно ожидаемое событие на trigger, отсутствие события для exclusions, правильные timestamp и IDs, одинаковые properties в web, mobile и backend sources.

### В production

По каждому event и producer отслеживайте:

- observed и expected event names;
- наличие required properties;
- type и enum violations;
- duplicate rate;
- задержку между event time и ingestion time;
- изменение volume и distinct IDs;
- новые high-cardinality properties;
- неожиданные personal и free-text поля.

Не копируйте универсальную цель `99%` completeness или порог anomaly `50%`. Service levels зависят от business criticality и нормальной вариативности. Billing event может требовать почти полного reconciliation с ledger; потеря части малозначимых UI exposures допустима.

Критичные failures должны попадать в общий [процесс metric alerts](/ru/blog/automated-metric-alerts/) вместе с product и infrastructure signals. Alert без owner, runbook и reconciliation path быстро становится фоновым шумом.

Managed tools умеют хранить, ветвить, подтверждать и проверять schemas. Amplitude сейчас поддерживает tracking-plan branches и official designations; Segment Protocols валидирует события по плану. Маленькая команда может начать с versioned JSON или CSV, runtime validation и CI tests. Важен один authoritative contract с владельцем, а не логотип инструмента.

## Как менять schema и не ломать историю

Классифицируйте изменения:

- **Additive:** новая optional property или event.
- **Compatible tightening:** документация enum или validation, совпадающая с существующими данными.
- **Breaking:** rename, новый grain, другая firing point, смена type или новый смысл под старым именем.
- **Deprecation:** прекращение новых записей при сохранении исторической трактовки.

Для breaking change создайте новую version или event name. Параллельно отправляйте старую и новую схему только при необходимости, обновите зависимые dashboards, затем выключите старый producer. Не переименовывайте historical data в новый смысл ради аккуратного каталога.

Запишите решение:

```yaml
change: invoice_paid v1 -> v2
reason: event now represents settlement, not authorization
effective_at: 2026-09-01T00:00:00Z
owners:
  producer: billing-engineering
  consumers: finance-analytics
migration:
  - add v2 payload and validation
  - reconcile v2 against payment ledger
  - update revenue dashboards
  - deprecate v1 after named consumers move
```

## Практическая последовательность

1. Выпишите решения и вопросы, которые должны поддержать данные.
2. Определите metrics, entity, cohort и time windows.
3. Выберите event grain, producer, source of truth и identity behavior.
4. Примите единые naming и property rules.
5. Опишите contracts с privacy и lifecycle metadata.
6. Используйте AI для mapping переданных evidence, а не создания product truth.
7. Реализуйте минимальный полезный slice.
8. Тестируйте raw payloads, schemas и reconciliation критичных фактов.
9. Следите за качеством по event и producer.
10. Версионируйте semantic changes и осознанно отключайте obsolete data.

Надёжная event taxonomy — не самый длинный список событий. Это минимальный общий язык, на котором product, engineering и analytics получают воспроизводимый ответ.

## Источники

- [Amplitude: taxonomy versus tracking plan](https://amplitude.com/taxonomy-generator)
- [Amplitude: CSV tracking-plan branches](https://amplitude.com/docs/data/csv-import-export)
- [Amplitude: official events and properties](https://amplitude.com/docs/data/official-events-and-properties)
- [Twilio Segment: create a tracking plan](https://app-canary.segment.com/academy/collecting-data/how-to-create-a-tracking-plan/)
- [Twilio Segment: tracking-plan validation](https://segment.com/data-hub/data-validation/)
- [PostHog: analytics naming guidance](https://newsletter.posthog.com/p/what-engineers-get-wrong-about-analytics)
- [European Commission: GDPR processing principles](https://commission.europa.eu/law/law-topic/data-protection/information-business-and-organisations/principles-gdpr_en)
- [ICO: pseudonymisation guidance](https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/data-sharing/anonymisation/pseudonymisation/)
