Прод
есть находкиПроверок прогнано 14, с находками 4. Заняло 336.6 с.
· версия 0.16.0-alpha
Что проверено, когда и с каким исходом. Зелёное здесь означает «проверено недавно и сошлось»: результат старше полутора суток отмечается как неизвестный, потому что доска, показывающая вчерашнее за нынешнее, хуже отсутствующей.
Проверок прогнано 14, с находками 4. Заняло 336.6 с.
· версия 0.16.0-alpha
Всего проверок 65, из них 9 умеет прогнать само приложение — они и попадают в ночной прогон. Остальные запускаются командой и здесь перечислены, чтобы было видно не только что проверено, но и что нет. Рядом с ними 6 отчёта: они читаются глазами и помечены отдельно.
| Проверка | Что сверяет | Команда | Состояние |
|---|---|---|---|
| Осмотр перед запуском | Отвечает ли база, нет ли в журнале отметки dev, долгих транзакций, раздутых таблиц и непроверенных ограничений. Сверку журнала со схемой осмотр обещал, но не делал — она в migrate:baseline и стоит десятков запросов | doctor | Прод |
| Присмотр за пулом соединений | У обрыва соединения ровно один слушатель: без него обрыв убивает процесс, а лишние пишут в лог по копии на каждый | check:pool | ещё не гонялась |
| Куда уходит время самой медленной страницы | Каждый шаг сборки данных замеряется отдельно, и рядом — тот же шаг дешевле. Без разложения починку кладут туда, где правдоподобно, а не туда, где секунды | audit:slow | отчёт: читается глазами, упасть не может |
| Индексы против запросов | Какие индексы не используются и каких не хватает под настоящую нагрузку. Порога «допустимо» у этого нет: решение об удалении индекса принимает человек, а ревизия даёт ему счёт и готовые команды | audit:indexes | отчёт: читается глазами, упасть не может |
| Следствия записи наступают после коммита, а не внутри него | Журнал правок, снимки оценок и пересчёт индекса обещают, что их отказ не отменит саму запись. Пока они шли в одной транзакции с ней, обещание было невыполнимо: упавший запрос делает транзакцию неспособной к коммиту, и вместе со следствием откатывалась запись. Проверяется попыткой: до коммита работа не выполняется, после — выполняется ровно раз, после отката — никогда | check:after-commit | ещё не гонялась |
| Границы в базе и границы в форме — одни и те же | Ограничение базы разрешает жирность до пятнадцати процентов, а поле формы не разрешало ничего: границ у него не было вовсе. Человек вводил двести, нажимал «Сохранить» и получал вместо понятного отказа сырое имя ограничения | check:bounds | ещё не гонялась |
| Схема базы совпадает с ожиданиями Payload | Поле, добавленное в коллекцию без миграции, ломает запись молча: типы переписаны, а колонки в базе нет. Требует PAYLOAD_DB_PUSH=false — при включённом push Payload устраняет расхождение до того, как проверка его измерит | check:schema | гоняется вручную |
| Проверка | Что сверяет | Команда | Состояние |
|---|---|---|---|
| Отчёты по стаду считаются | Семь запросов выполняются на живой базе и возвращают то, что обещает тип | check:herd | Прод |
| Списки сходятся с числами | Число в отчёте равно длине списка за ним: несходящееся число хуже ошибки — оно правдоподобно с обеих сторон | check:drilldown | Прод |
| Сервис-период на экране и в реестре — одно число | Отчёт по стаду и выгрузка во ФГИАС ПР считают сервис-период на одних животных и обязаны сойтись день в день: разными они были полгода — на экране дни до первого осеменения, в реестре до плодотворного, и оба под одним именем | check:service-period | гоняется вручную |
| Проставленные значения ловятся, а не только объявлены | Правило смотрит на форму распределения жира в контрольном дне и состоит из двух половин, которые ломаются по-разному: арифметика — от правки формулы, запрос — от переименованной колонки. Прогон проверяет обе, потому что зелёная арифметика при неработающем запросе выглядит точно так же, как исправное правило | check:stamped | ещё не гонялась |
| Возраст первого отёла — одно число на четырёх экранах | Отчёт хозяйства, сводка Ассоциации, карточка быка и отчёт по производителям считают возраст первого отёла разными запросами и обязаны сойтись с перебором документов: до общего куска SQL один бык показывал на четырёх страницах четыре разных числа | check:afc | гоняется вручную |
| Ассоциация и хозяйство видят одно и то же | Сводка по стадам считается группировкой по всем хозяйствам, кабинет — по одному; разойдись они, Ассоциация позвонит про беду, которой хозяйство у себя не видит | check:condition | ещё не гонялась |
| Ревизия зоотехнических правил | Все правила реестра прогоняются по настоящим данным: какие срабатывают, какие молчат | audit:checks | Прод |
| Родословная без противоречий | Циклы в родословной, родители моложе потомков, животное само себе родитель, невозможный возраст родителя — по тем же порогам, что видит эксперт | audit:pedigree | Прод |
| Подбор пар считается верно | Инбридинг сверяется на случаях с известным ответом: полусибсы, полные сибсы, отец с дочерью | check:mating | пишет в базу — гоняется только на копии |
| Сравнение быков со сверстницами | Разница по дочерям считается на построенном контрольном стаде | check:bulls | пишет в базу — гоняется только на копии |
| Приплод сходится сам с собой | Тип рождения, числа живых и мертворождённых и карточки телят — на выдуманных отёлах, без базы | check:calving | гоняется вручную |
| Рейтинг не врёт местами | Разряды не пересекаются, порядок не возрастает, совпадения делят место, а отбор по хозяйству мест не сдвигает | check:ranking | гоняется вручную |
| Разброс признака: заявленный против измеренного | Индекс делит отклонение каждого признака на его стандартное отклонение, и числа σ у нас заимствованные; у смертности приплода подставлено отклонение живучести коров — то есть измеренное на других животных. Спорить, какое чужое число взять, бессмысленно: разброс оценок в своей книге считается, и прогон его считает. Он ничего не правит и не падает — замена σ меняет порядок всех животных в рейтинге | check:trait-sd | гоняется вручную |
| Выбытие без даты выбытия и цена этой дыры | Отчёты о выбытии считают по дате, а не по состоянию, а дату ставили не все дороги ввода: перемещение и событие ленты ставили, поле «Состояние» в карточке и загрузка файлом — нет. Такое животное уходит из знаменателя и не попадает в числитель, то есть занижает долю выбытия дважды и молча. Прогон считает, скольких это касается и на сколько врёт отчёт: рядом с нынешней долей встаёт верхняя оценка настоящей | check:disposal-date | ещё не гонялась |
| Возрастная группа против факта отёла | Сколько записей стоят не в своей возрастной группе и сколько поднимет пересчёт — счёт по живой книге, без порога «допустимо» | check:cow | отчёт: читается глазами, упасть не может |
| Проверка | Что сверяет | Команда | Состояние |
|---|---|---|---|
| Чужое закрыто | Попытки поднять себе роль и прочитать чужие записи отклоняются | check:security | пишет в базу — гоняется только на копии |
| Уровень достоверности выводится, а не ставится | Протокол лаборатории поднимает вторую ступень, отзыв её снимает, а подпись Ассоциации ни то ни другое не трогает. Отдельно — ступень «Отклонено»: она ставится поверх подписи, протокол её не снимает, а новая заявка снимает и возвращает ту ступень, которая следует из книги | check:trust | пишет в базу — гоняется только на копии |
| Роли, приглашения, блокировка | Сотрудник видит своё, приглашение работает один раз, заблокированный не входит | check:team | пишет в базу — гоняется только на копии |
| Границы хозяйств | От лица настоящего пользователя: не видно и не правится ничего чужого | audit:tenancy | пишет в базу — гоняется только на копии |
| Точечные доступы | Выданный доступ открывает ровно одну запись и отзывается | audit:grants | пишет в базу — гоняется только на копии |
| Заслон подтверждения | Показывает очередь заявок и то, что заслон сказал бы по каждой: какие находки держат подтверждение и чего в данных не хватает | audit:gate | отчёт: читается глазами, упасть не может |
| Журнал переживает предмет | Запись об операции остаётся после удаления того, о чём она | check:journal | пишет в базу — гоняется только на копии |
| Сохраняемые отборы | Отбор сохраняется, открывается и удаляется, чужой не виден | check:searches | пишет в базу — гоняется только на копии |
| Проверка | Что сверяет | Команда | Состояние |
|---|---|---|---|
| Выгрузка и загрузка книги Excel | Настоящее стадо выгружается, читается обратно и сходится с исходным | check:xlsx | пишет в базу — гоняется только на копии |
| Выгрузка во ФГИАС ПР | Шапка сходится с настоящим шаблоном, наш ключ не выдаётся за номер реестра | check:fgias-export | гоняется вручную |
| У пород есть коды ICAR | Без трёхбуквенного кода порода не уезжает в обмен вовсе, а международный номер собирается коротким: шестнадцать символов вместо девятнадцати | check:breed-codes | гоняется вручную |
| Международный номер собирается и разбирается верно | Настоящие номера из чешских списков быков разбираются; импортное животное считается от страны происхождения; длинный номер не обрезается | check:aiid | гоняется вручную |
| Ресурсы ICAR ADE собираются по спецификации | Имена полей и значения перечислений из стандарта, время в UTC, показатель молока строкой, ноль не выдан за «неизвестно» | check:ade | гоняется вручную |
| Кодировки и разделители CSV | windows-1251 и UTF-8, точка с запятой и запятая, круговой прогон разбора и сборки | check:csv | Прод |
| Смена владельца | Животное переходит с историей, прежний владелец теряет доступ | check:movements | пишет в базу — гоняется только на копии |
| Описание API полное | Все ручки попадают в OpenAPI: описание, разошедшееся с кодом, хуже отсутствующего | check:openapi | Прод |
| Фильтры выборки называются именами стандарта | Фильтр со своим именем работает и при этом бесполезен: клиент шлёт meta-modified-from, мы ждём своё — и партнёр получает всю книгу вместо изменённого за сутки, без единой ошибки | check:ade-filters | гоняется вручную |
| Каталог пород собран из справочников | Код породы, сопоставленный на глаз, уезжает в международный номер животного и объявляет чужой стране чужую породу; состояние «книга ведётся» обязано следовать из действующей книги, а не из галочки | check:breeds | гоняется вручную |
| Лента изменений: метки и опознание удалённого | Идентификатор надгробия, разошедшийся с тем, под которым ресурс уезжал, — это удаление, которого партнёр не заметит: у него всё сойдётся, а корова, которой нет, продолжит доиться | check:ade-generic | гоняется вручную |
| Обмен отвечает по сети так, как обещано | Между разобранным фильтром и полученными данными лежит слой, который не видит ни одна проверка кода: маршрут, схема локации в адресе, заголовки, коды отказов. Ошибка в нём выглядит как пустой ответ — неотличимо от «данных нет» | check:ade-live | нужен обход снаружи — место в ночном действии |
| Отдаваемое сверяется с настоящими схемами ICAR | Своя копия перечислений не поймает изменения стандарта: и проверяемое, и проверяющее написаны одной рукой. Здесь проверяющее написано ICAR | check:ade-schema | гоняется вручную |
| Приём по ICAR ADE разбирает данные верно | Своя выгрузка обязана проходить свой же приём, а «3,5» вместо 3.5 — отвергаться: принятая запятая даёт тридцать пять процентов жира | check:ade-accept | гоняется вручную |
| Готовность книги к выгрузке в реестр | Реестр отвергает запись целиком из-за одного незаполненного поля; отчёт считает, сколько животных уедет, а сколько вернётся, и по какой колонке | check:fgias-readiness | отчёт: читается глазами, упасть не может |
| Разбор чисел и дат из чужой таблицы | «5.03.2026» разбирается прекрасно — во второе марта; проверка утверждает сами значения, а не то, что файл загрузился | check:import-values | гоняется вручную |
| Загрузка чужих форматов, файл за файлом | Кодировка, разделитель и разбор значений проверяются по отдельности; здесь настоящий файл проходит весь путь целиком — и печатается, где загрузка портит данные молча | check:import-formats | отчёт: читается глазами, упасть не может |
| Проверка | Что сверяет | Команда | Состояние |
|---|---|---|---|
| Соответствие подтверждается, а не заявляется | Каждое доказательство на странице соответствия ведёт на существующий прогон, файл или адрес; у «выполнено» и «частично» доказательство обязательно | check:compliance | гоняется вручную |
| Домены разводятся верно | Витрина и книга живут на разных доменах одного приложения; ошибка тут не падает, а показывает не то — рекламу вместо кабинета | check:hosts | гоняется вручную |
| Принадлежность книги отделена от системы | Имя, адрес, телефон и почта организации берутся из настройки книги, а не вписаны в страницы; иначе показательная книга покажет чужие реквизиты, и заметить это можно только открыв её | check:tenant | гоняется вручную |
| Ссылки не вложены друг в друга | Вложенные <a> недопустимы по HTML: браузер перестроит разметку по-своему, и жалоба придёт на гидратацию, а не на причину | check:links | гоняется вручную |
| Обход всех страниц | Каждая страница живого сервера отвечает, битых ссылок и переадресаций нет | smoke | пропущена |
| Ссылки навигации ведут куда обещают | Все пункты меню кабинета открываются на живом сервере с живой базой | check:nav | пропущена |
| Страница API открывается | Документация отдаётся и её обвязка лежит на месте | check:api-docs | пропущена |
| Английская витрина остаётся английской | Абзац, набранный прямо в разметке, не виден ни одной проверке переводов — и английская страница молча становится наполовину русской; проверяются и наборы строк (есть ли английская ветка и нет ли в ней кириллицы), и сама разметка витрины | check:english | гоняется вручную |
| Обещанный язык подкреплён словарём | Полноту словаря данных проверяет тип, но не его существование: язык, добавленный в locales.ts без словаря, молча отдаёт русский, а объявленный вычитанным — отдаёт его уже и без оговорки; заодно ловится строка, скопированная из русского, — она компилируется, выглядит переводом и глазами не опознаётся | check:languages | гоняется вручную |
| Страницы шаблонов реестра сходятся с контрактом | Двадцать страниц отвечают тому, кто открыл файл реестра и не понимает, что писать, и вся их ценность в точности: имя колонки, приведённое приблизительно, бесполезно — по нему ищут строку в своём файле и не находят. «Дата отёла» вместо «Дата отела» пишется рукой сама, потому что в контракте «ё» стоит не везде | check:fgias-pages | гоняется вручную |
| Каждый адрес витрины открывается | Проверки витрины читают код и ни одна не открывает страницу — так словарь и раздел исследований выложились с ошибкой сервера на каждом адресе статьи: сборка прошла, типы сошлись, указатели открывались, и поломка выглядела бедой отдельных страниц. Адреса берутся из карты сайта, чтобы новый раздел попадал под прогон сам, а не вносился в список руками | check:site | нужен обход снаружи — место в ночном действии |
| Словарь не обещает лишнего | Ссылка «читать дальше» на разбор или соседний термин выглядит рабочей всегда — подчёркнута и нажимается, — и о том, что её адреса нет, узнаёт только читатель, получив «страница не найдена»; заодно ловится статья короче двухсот пятидесяти слов, которой место строкой в указателе, и определение, не помещающееся в строку выдачи | check:terms | гоняется вручную |
| Разметка для поисковых систем не ссылается в пустоту | Разметка собрана из того же, из чего нарисована страница, и сверять её с текстом незачем; ломается она снаружи — переименованный файл знака, ссылка на узел, которого никто не объявил, снятый с главной вызов, после которого повисают одиннадцать разборов сразу. Ни одно из этого на странице не видно: картинка из разметки нигде не показывается, а отказ получает только робот | check:jsonld | гоняется вручную |
| Метатеги постранично | Страница без описания открывается, выглядит правильно и просто хуже находится — заметить это глазами нельзя ни на одной отдельной странице; заодно ловится заголовок, повторяющий хвост, который приклеит раскладка («… племенная книга — Племенная книга»: склеенную строку видно только в выдаче), и считается долг по переводу — русский текст, набранный прямо в разметке, ни одна проверка переводов не видит | check:seo | гоняется вручную |
| Числа в текстах против чисел в коде | Витрина и техническое описание называют количества — правил проверки, ограничений базы, коллекций обмена, — и это доказательство, ради которого страницу и читают. Устаревают такие числа молча: правило добавили, текст остался прежним. Держать их руками не удалось дважды: в описании стояло «пятьдесят три правила» при семидесяти семи в реестре и «тридцать проверок» в базе при сорока двух, и обе цифры врали месяцами ровно тому, кто пришёл за точностью. Ненайденное утверждение считается отказом наравне с разошедшимся числом: переписанная фраза делает прогон зелёным и бесполезным | check:numbers | гоняется вручную |
| Разборы: страница, паспорт, источники | Разбор живёт в двух местах — строкой в списке и страницей; разъехавшись, они дают либо «страница не найдена» тому, кого мы позвали читать, либо страницу, куда никто не ведёт. Ссылка на первоисточник обязательна: без неё разбор превращается в пересказ, от которого весь раздел и отличается | check:notes | гоняется вручную |
| Нарисованные экраны разделов доходят до страницы | Опечатка в сравнении со слугом раздела не ошибка ни для языка, ни для типов: ветка просто не выполняется, и страница молча остаётся без рисунка; обратное тише — экран написан, вывезен наружу и нигде не вставлен | check:screens | гоняется вручную |
| Исследования: части заполнены, требования не отстали от кода | У разборов проверка была, у шести исследований — ни одной, а устроены они сложнее: семь частей, список требований к книге, свои источники. Требования успели отстать от кода и просили завести то, что уже заведено. Проверяются непустота частей, внешние ссылки с пояснением «что взято», существование внутренних адресов и то, что у требования есть место в коде | check:studies | гоняется вручную |
| Проверка | Что сверяет | Команда | Состояние |
|---|---|---|---|
| Серверные компоненты не передают функций | Пропс-функция через границу «сервер → клиент» роняет сборку, и только её — в разработке страница работает | check:client-props | гоняется вручную |
| Переводы полны, а язык определяется как задумано | Ни одной пустой строки и ни одного русского абзаца в нерусском языке; Accept-Language разбирается верно, а выбор человека сильнее догадки | check:i18n | гоняется вручную |
| Хуки коллекций пишут внутри своей транзакции | Ни одно обращение к Payload из хука не идёт мимо `req` — иначе не ошибка, а зависание | check:hooks | гоняется вручную |
| Раскладка, которую не видно на одной странице | Меню кабинета стоит выше заголовка на каждой странице; раскладка задаётся классами, а не свойством в style — свойство действует на любой ширине и старше класса, поэтому соседний grid-cols-1 или sm:flex-row рядом с ним молча перестаёт работать, и вёрстка ломается только на телефоне | check:layout | Прод |
| Даты в четырёх часовых поясах | Показ дат не съезжает на сутки при смене пояса читателя | check:time | Прод |
| Реестр проверок совпадает с тем, что можно запустить | Проверка без записи в реестре невидима на этой самой странице, а запись без команды обещает запуск, которого не будет | check:registry | гоняется вручную |
Находок: 8. Что именно не сошлось, видно вошедшим: разбор называет номера животных, а это уже данные книги, а не сведения о системе.
audit:pedigree