fix(record): reopen latest closed по max(validTo) + revert i18n

This commit is contained in:
Александр Зимин
2026-06-22 10:00:38 +00:00
parent b84ef94121
commit 3cc7410ab5
2 changed files with 10 additions and 9 deletions
@@ -158,7 +158,7 @@ export const RecordHistoryDrawer = ({
onClick={() => onRevert(rec.data, displayVersion)} onClick={() => onRevert(rec.data, displayVersion)}
leftIcon={<ArrowCounterClockwiseIcon weight="regular" size={14} />} leftIcon={<ArrowCounterClockwiseIcon weight="regular" size={14} />}
> >
{t('history.revert', { defaultValue: `Откатить к v${displayVersion}` })} {t('history.revert', { v: displayVersion, defaultValue: `Откатить к v${displayVersion}` })}
</Button> </Button>
)} )}
{isLatest && status === 'expired' && onReopen && ( {isLatest && status === 'expired' && onReopen && (
@@ -441,17 +441,18 @@ public class DictionaryRecordService {
"business_key='" + businessKey + "' уже активен — re-open не нужен."); "business_key='" + businessKey + "' уже активен — re-open не нужен.");
} }
// findByDictionaryIdAndBusinessKeyOrderByValidFromDesc возвращает версии // Самая недавно закрытая версия = max(validTo) среди closed с НЕпустым
// отсортированными по validFrom desc. Самая недавно закрытая — это первый // периодом. Берём по validTo, а не по validFrom: при UPDATE/CLOSE в один
// элемент, у которого validTo != FAR_FUTURE (closed) и validTo больше всех // момент возможны zero-length версии (validFrom == validTo) — артефакты,
// других closed. Так как версии bitemporal не пересекаются (exclusion // которые "никогда не были активны". Их фильтруем (isAfter validFrom),
// constraint), а closed period — последний по validFrom, то это и есть // иначе re-open восстановил бы пустую версию вместо реально закрытой.
// первый matching элемент.
var prevData = repository var prevData = repository
.findByDictionaryIdAndBusinessKeyOrderByValidFromDesc(d.getId(), businessKey) .findByDictionaryIdAndBusinessKeyOrderByValidFromDesc(d.getId(), businessKey)
.stream() .stream()
.filter(r -> r.getValidTo() != null && r.getValidTo().isBefore(FAR_FUTURE)) .filter(r -> r.getValidTo() != null
.findFirst() && r.getValidTo().isBefore(FAR_FUTURE)
&& r.getValidTo().isAfter(r.getValidFrom()))
.max(java.util.Comparator.comparing(DictionaryRecord::getValidTo))
.orElseThrow(() -> OrdinisException.notFound( .orElseThrow(() -> OrdinisException.notFound(
"record_not_closed", "record_not_closed",
"Нет закрытой версии business_key='" + businessKey + "' для re-open.")); "Нет закрытой версии business_key='" + businessKey + "' для re-open."));