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

Отчёты, диффы и доставка ​

У движка две поверхности чтения. stats — снимок метрик по провайдерам для дашборда; report weekly собирает дайджест, сохраняет его и может доставить. Обе используют одни и те же окна с учётом часового пояса и одни и те же поля честности.

См. также: Источники данных и квоты, Обход и аудит, Автоматизация и доставка, MCP и навыки агентов.

stats и report weekly ​

statsreport weekly
НазначениеМетрики по провайдерам для дашбордаСобранный недельный дайджест
ПровайдерыGSC, Yandex Webmaster, Metrika, Bing, CrUX, PSI, всегда в этом порядкеТе же провайдеры плюс сохранённые проблемы обхода
ЗаписьНичего; SQLite не нуженСохраняет недельный снимок при наличии хранилища
ДоставкаНикогдаТолько с --send
СравнениеТекущее и предыдущее окна по каждому провайдеруЗаголовочная дельта GSC, трафик по движкам, возможности
ВыводJSON-конверт или короткая текстовая таблицаJSON, HTML, текст для email или Telegram
bash
lv24-seo stats --days 7 --lag-days 2 --json
lv24-seo report weekly --days 7 --lag-days 2 --out reports/
lv24-seo report weekly --days 7 --lag-days 2 --send --json

stats сообщает status как ok, no_data, missing_token, not_configured или error и изолирует сбой провайдера: конверт остаётся ok: true, а coverage.failed увеличивается. metrics содержит только реально полученные значения, без заполнения нулями и без межмоторных итогов. previous есть только для сопоставимых окон GSC, Yandex Webmaster и Metrika; Bing, CrUX и PSI возвращают null.

coverage.complete истинно, только когда каждый настроенный сервис имеет статус ok, вернул строки, не усечён и ничего не пропало и не упало. Если ни один провайдер не настроен, значение ложно.

Окна и лимиты ​

  • --days — длина текущего окна от 1 до 3660. Большее значение завершается с INVALID_INPUT и кодом выхода 2, а не строит неограниченное окно.
  • --lag-days сдвигает оба окна назад и принимает 0 или больше. Предыдущее окно — такое же по длине окно непосредственно перед текущим.
  • Данные GSC отстают на 2–3 дня, поэтому отчёт в понедельник утром стабилен. По умолчанию 7 дней и задержка 2 дня.
  • Окна используют report.timezone. Даты провайдеров не конвертируются.
  • MCP seo_weekly_report ограничивает days сверху 90, а lag_days — 14, с предупреждением; значения ниже минимума отклоняются. CLI принимает полный диапазон 1–3660. Для длинного периода используйте CLI.

Что содержит недельный отчёт ​

Заголовок сравнивает клики, показы, CTR и среднюю позицию GSC на двух одинаковых окнах. Изменение CTR выражается в процентных пунктах (pp). Если сопоставимого окна GSC нет, отчёт сохраняет реальные текущие значения с previous: null и сообщает, что дельта недоступна; он не выдумывает базу и не объединяет движки в общий итог.

Цифры по движкам остаются раздельными:

  • Yandex Webmaster: текущее окно топ-запросов, в недельном дайджесте ограничено 500 строками.
  • Yandex Metrika: сессии, а не клики.
  • Bing, CrUX и PSI: дополнительные строки движков, если настроены. CrUX — полевые данные, PSI — лабораторные, и они никогда не смешиваются.

Отчёт также содержит ранжированные возможности (близкая дистанция, разрыв CTR, падающие страницы), проблемы по серьёзности из последнего сохранённого обхода, раздел источников, заметки о данных и ограничения. Каждая возможность несёт реальные доказательства и ожидаемые клики — это оценка приоритета, а не обещание трафика.

JSON-конверт также содержит meta.complete, meta.sources, meta.sources_failed, meta.sources_missing, meta.sources_incomplete, meta.data_age_days, meta.truncated, meta.limitations, meta.locale и meta.snapshot_hash.

Вывод и сохранённые снимки ​

bash
lv24-seo report weekly --out reports/

--out DIR пишет два файла:

  • report.json — канонический английский, стабильный для диффа между запусками.
  • report.html — отрисован в report.locale.

Недельный запуск также сохраняет снимок в data/seo.sqlite3, если каталог данных существует. lv24-seo init создаёт <config dir>/data; относительный [storage] data_dir привязывается к файлу конфигурации, а LV24_SEO_DATA_DIR остаётся process-scoped переопределением. Без хранилища команда предупреждает, что снимок не сохранён.

Снимки ключуются по виду, свойству и периоду. Они питают report diff; журнал отправок живёт в том же файле SQLite. MCP держит последний отчёт в памяти для seo://report/latest. report.json, конверты --json и report diff --markdown остаются каноническим английским, даже когда язык отображения русский или китайский; машинные коды не переводятся.

Как читать truncated и limitations ​

Перед выводом проверьте конверт в таком порядке:

  1. ok и meta.complete — вернул ли каждый настроенный источник пригодные строки?
  2. meta.truncated — ограничил ли провайдер данные?
  3. meta.data_age_days — насколько окно старше момента запроса?
  4. meta.limitations[] и warnings[] — что неизвестно или приблизительно?

Метрика, присутствующая только в одном окне, неизвестна, а не равна нулю. Усечённый ответ не полон. Последняя страница GSC, точно заполнившая лимит 50 000 строк, помечается усечённой, а не полной: полная страница не доказывает отсутствие следующей строки. Сбой провайдера не валит отчёт: email называет отсутствующий источник, конверт выставляет complete: false, а остальные движки всё равно возвращают данные.

Локализация ​

report.locale принимает ru, en и zh; по умолчанию ru. Он управляет темой письма, HTML и простым текстом, человекочитаемой сводкой CLI, HTML из --out и сообщениями Telegram, включая форматирование чисел, процентов, позиций, дат и множественного числа.

Локаль влияет только на представление. JSON-конверты, payload MCP, сохранённые снимки и report diff остаются каноническим английским. Неподдерживаемая локаль отклоняется при валидации конфигурации с CONFIG_INVALID, а не подменяется молча.

Email и Telegram ​

Email использует SMTP на порту 587 с STARTTLS и проверяющим TLS-контекстом. Вход выполняется только после успешного TLS. Сообщение — multipart/alternative: HTML-шаблон продукта и тот же контент простым текстом в 78 колонок, с локализованной темой в одну строку не длиннее 78 символов.

Шаблон — карточка 600px с inline CSS, тёмной шапкой и текстовым словесным знаком. В нём нет внешних изображений, таблиц стилей, скриптов, трекинговых пикселей и удалённых шрифтов. Неизвестные KPI отображаются локализованным текстом «Нет данных», а не 0 и не длинным тире. Metrika показывается как сессии, а не клики. Пустой раздел проблем сообщает, что данных о проблемах нет, вместо заявления, что сайт чист. Ограничения и предупреждения сохраняются и дедуплицируются; текст провайдера остаётся на исходном языке и помечается как оригинал, когда отчёт локализован. В подвале — точный id свойства, время генерации в UTC и «generated by lv24-seo».

Telegram отправляет тот же локализованный текст в 78 колонок через метод Bot API sendMessage. Ответы HTTP 4xx/5xx, таймауты транспорта и некорректные ответы Bot API помечаются как failed и никогда не записываются как отправленные.

Существуют только каналы email и Telegram. Нет адаптеров Resend или Brevo и нет --channel github; отправка GitHub issues провайдером не реализована.

Идемпотентность и гарантии доставки ​

Журнал sends уникален по (kind, property, period, channel, content_hash). Хеш покрывает заголовок и разделы плюс нормализованную локаль рендера, а generated_at и диагностика исключены. Английский не включает локаль в хеш, поэтому обновление не переотправляет уже доставленный английский период.

only_on_change пропускает отправку, если хеш контента уже доставлялся (already_sent). Материальный фильтр пропускает её, если ни одно изменение не достигает report.thresholds (no_material_change). Фильтр работает до проверки хеша локали, поэтому чистое переключение языка может быть подавлено, когда в периоде нет материального изменения; оно доставляется, когда фильтр проходит или отключён.

Доставка — at-least-once на канал. Неоднозначный результат транспорта помечается failed и не записывается, поэтому следующий запуск может доставить дубль. Параллельные запуски дедуплицируются транзакцией SQLite вокруг проверки, отправки и записи в журнал; SMTP и Bot API не дают exactly-once после падения процесса. Держите одно расписание на период.

Сравнение сохранённых снимков ​

bash
lv24-seo report diff --json
lv24-seo report diff --base 2026-11-02..2026-11-08 --head 2026-11-09..2026-11-15 --markdown

report diff сравнивает два сохранённых недельных снимка, не вызывая провайдеров. По умолчанию берутся два самых новых периода. Он показывает изменения заголовочных метрик, количество проблем по серьёзности, добавленные, решённые и неизменные возможности, а также добавленные и снятые ограничения.

Метрика, присутствующая только в одном снимке, попадает в unknown_metrics, а не в ноль. comparable и meta.complete ложны, если в одном из снимков нет заголовочного сравнения или длины периодов различаются. --markdown печатает только GitHub-flavoured Markdown, предупреждения идут в stderr, поэтому stdout остаётся валидным для комментария PR или сводки CI. Markdown-дифф перечисляет не более 20 возможностей на группу и сообщает, сколько ещё есть.

Команде нужны lv24-seo init и два запуска report weekly за разные периоды. Без хранилища она падает с CONFIG_INVALID; при менее чем двух снимках — с INVALID_INPUT. Оба случая несут next_action.

Source: _source/engine-cli.md, _source/engine-scheduling.md, _source/engine-releases-0.5.2.md.