fix: publish valid SRO memberships while preserving quarantined history
All checks were successful
Mostovik Backend CI/CD / Tests and lint (push) Successful in 2m55s
Mostovik Backend CI/CD / Build linux/amd64 release images (push) Successful in 3m48s
Mostovik Backend CI/CD / Deploy and verify internal main (push) Has been skipped
Mostovik Backend CI/CD / Deploy customer main (push) Has been skipped
Mostovik Backend CI/CD / Deploy dev (push) Successful in 1m54s

This commit is contained in:
Aleksandr Meshchryakov
2026-09-15 13:25:43 +02:00
parent 3d7fb78678
commit 2cfc057e34
7 changed files with 471 additions and 22 deletions

View File

@@ -120,14 +120,28 @@ static или reverse-proxy document root. Существующая retention-к
fallback на public raw нет.
Публикация записей, checkpoint организаций, load log и terminal job выполняется
в одной транзакции. Инкрементальная публикация заменяет данные только успешно
проверенного набора организаций; записи остальных организаций сохраняются.
Transport/schema failure или отменённая job откатывает публикацию и checkpoints.
Допустимый пустой ответ удаляет старые членства проверенной организации.
Любая семантически некорректная строка остаётся в quarantine и отклоняет весь
запуск с `sro_incomplete_membership_scan`. Это сохраняет прежние членства и
checkpoints: неизвестный статус или неразрешённая ссылка не доказывают, что
членство исчезло. Организация остаётся кандидатом следующего incremental запуска.
в одной транзакции после завершения сбора всех кандидатов. Transport/schema failure,
нарушение целостности или отменённая job откатывает публикацию и checkpoints целиком.
Незавершённый batch остаётся диагностическим и не становится current snapshot.
Завершённый сбор может закончиться `success` с quarantine, как в примере истории
исходного контракта. Валидные строки публикуются, включая валидные членства организации,
у которой другая строка оказалась некорректной. Неизвестный статус, отсутствующий
SRO ID или URL, конфликт идентификаторов не исправляются догадками: исходная строка
остаётся в quarantine с причиной. У таких организаций прежние членства, не обновлённые
валидной строкой этого batch, сохраняются с прежними UID, payload и load batch.
Ошибка в строке не доказывает прекращение других членств. Для полностью проверенных
организаций исчезнувшие членства удаляются; допустимый пустой ответ удаляет их все.
При incremental неизменённые, не опрошенные организации также сохраняются.
Checkpoint полностью проверенной организации обновляется. У организации с quarantine
прежний checkpoint удаляется в той же транзакции, чтобы следующий incremental повторил
lookup даже при неизменившемся fingerprint. Raw artifact и staged audit сохраняются.
Если нет ни одной валидной строки и ни одного подтверждённого пустого lookup `200`,
quarantine отклоняет запуск с `sro_incomplete_membership_scan`; смесь invalid rows
и неоднозначных `404` не считается подтверждённым отсутствием. Для полностью состоящего
из `404` запуска сохраняется отдельный `sro_ambiguous_empty_scan`. В обоих случаях
прежние записи и checkpoints остаются без изменений.
Если incremental не нашёл изменившихся организаций, batch имеет нулевую дельту
и наследует source registry date/version последней успешной публикации; ссылка
@@ -144,8 +158,16 @@ artifacts. Ошибка брокера после commit не превращае
общий результат, включая неизменённые организации. `metadata.snapshot_records_count`
и `snapshot_organizations_count` дают такие же общие record/distinct organization
counts; `batch_published_records_count` и `updated_records_count` — число опубликованных
строк текущей дельты. `parsed_count`, quarantine и candidate/queried counts относятся
к текущей проверке; складывать их с общим published count нельзя.
строк текущей дельты. При full с quarantine общий count также включает сохранённые
старые членства. `retained_records_count` — число старых строк организаций с quarantine,
которые не были обновлены валидным upsert и сохранены от удаления;
`quarantined_organizations_count` — число организаций хотя бы с одной строкой quarantine;
`completed_organizations_count` — число полностью проверенных организаций без quarantine,
включая допустимые пустые результаты. Эти три поля доступны в metadata API.
В приватном artifact `confirmed_empty_lookup_200_count` отдельно фиксирует подтверждённые
пустые `200` для проверки допустимости публикации. `parsed_count`, quarantine и
candidate/queried counts относятся к текущей проверке; складывать их с общим published
count нельзя. Новая дата публикации не изменяет прежнюю lineage сохранённых записей.
Источник публикует весь собственный справочник; карточка/list/dashboard для трёх
новых источников используют весь published scope. Coverage ОПК показывается