# События Аишки

Событие сохраняется вместе с бизнес-операцией в outbox. Worker присваивает последовательную позицию после commit. GET /api/v1/events возвращает доступные события и непрозрачный курсор; старше 30 дней курсор возвращает 410: заново прочитайте текущие сущности и начните новый курсор. Не выводите порядок событий из UUID.

Webhook сначала требует подтверждения владельцем точного HTTPS URL, затем успешной тестовой доставки worker. Только после 2xx он активен. Подпись Standard Webhooks: webhook-id, webhook-timestamp, webhook-signature; HMAC-SHA256 по id.timestamp.rawBody. Проверяйте исходные байты, окно 5 минут и дедупликацию event UUID. Ротация допускает старую подпись ещё 24 часа.

Доставка может повториться и прийти в другом порядке. Сохраняйте UUID в своей устойчивой очереди до ответа 2xx; повторно читайте актуальную revision перед действием. Приватные события проверяются по текущим правам при чтении и отправке. 410 требует resync.

Правила допускают notification, webhook и только разрешённые draft-команды. Произвольный код и вызов LLM внутри правила отсутствуют. Есть dry-run без эффекта, суточный лимит и защита цепочек. Отзыв ключа/grant или прав компании прекращает дальнейшее исполнение.

## Настройка без ручных запросов

Откройте /settings/integrations/#webhooks, выберите профиль, HTTPS-адрес, события и состав данных. Можно выбрать все события или отдельные группы. Подтвердите точный адрес кнопкой подключения. Секрет подписи генерируется автоматически; его нужно сохранить на принимающей стороне. История доставки и технические журналы обращений хранятся 7 дней; очистка выполняется каждый час. Незавершённые доставки остаются видимыми до завершения. История показывает реальные попытки и HTTP-ответы; очередь не означает доставку. Изменение адреса, событий или состава данных требует нового подтверждения и теста. Пауза и отключение отменяют ожидающие попытки; уже принятый получателем запрос отозвать нельзя.

## Состав данных

GET /api/v1/event-catalog — машиночитаемый справочник типов, полей, разрешений, примеров JSON и способов чтения сущности. Он также доступен ИИ через объявленный MCP-инструмент. GET /event-types сохраняет прежнюю совместимость.

Каждый обычный JSON содержит uuid, type, schemaVersion, occurredAt, aggregate (kind, uuid, revision), data и context. По умолчанию payloadMode=reference: data содержит objectUuid и status. В режиме current добавляются resourceReadAt и resourceStatus; resource содержит доступное представление текущей записи, если статус available. Это состояние на момент попытки, а не исторический снимок: повтор может содержать более новую редакцию. unavailable означает, что содержимое больше недоступно; too_large — превышен лимит представления 1 МиБ. Бинарные файлы не копируются в событие; вложенные ссылки не раскрываются рекурсивно. Все дополнительные чтения требуют действующих прав.

webhook.test — проверочный запрос с uuid, type, schemaVersion и data.test=true, без содержимого пользовательской записи. Заголовки подписи одинаковы для теста и обычного события.

## Реальные типы событий

- `complaint.created`
- `complaint.moderated`
- `deal.started`
- `deal.status_changed`
- `favorite.changed`
- `file.ready`
- `job_invitation.received`
- `job_invitation.status_changed`
- `job_invitation.withdrawn`
- `job_response.received`
- `job_response.status_changed`
- `job_response.withdrawn`
- `learning.appeal.opened`
- `learning.checker.failed`
- `learning.community.created`
- `learning.community.replied`
- `learning.community.resolved`
- `learning.course.completed`
- `learning.course.published`
- `learning.deadline.approaching`
- `learning.deadline.changed`
- `learning.enrollment.activated`
- `learning.enrollment.completed`
- `learning.enrollment.invited`
- `learning.enrollment.pause`
- `learning.enrollment.requested`
- `learning.enrollment.restored`
- `learning.enrollment.resume`
- `learning.enrollment.start`
- `learning.enrollment.transferred`
- `learning.enrollment.withdraw`
- `learning.enrollment.withdrawn`
- `learning.module.completed`
- `learning.review.overdue`
- `learning.review.requested`
- `learning.revision.requested`
- `learning.run.cancelled`
- `learning.step.available`
- `learning.submission.accepted`
- `learning.submission.graded`
- `message.received`
- `offer.received`
- `offer.status_changed`
- `offer.withdrawn`
- `profile.updated`
- `publication.deleted`
- `publication.draft_saved`
- `publication.hidden`
- `publication.moderated`
- `publication.restored`
- `publication.submitted`
- `response.received`
- `response.status_changed`
- `response.withdrawn`
- `review.moderated`
- `review.submitted`
- `task.closed`

[Готовые рецепты: импорт статей, Telegram, фотографии и ИИ](https://eval.su/docs/examples/recipes.md).
