refactor(consolidations): on_document_confirmed принимает автора и комментарий перехода (#64)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d9324f2a38
commit
ff65f2108b
@ -197,18 +197,22 @@ async def unbind_entity(session: AsyncSession, *, version_id: uuid.UUID, entity_
|
||||
return _rowcount(result)
|
||||
|
||||
|
||||
async def on_document_confirmed(
|
||||
async def on_document_confirmed( # noqa: PLR0913 - автор и комментарий перехода задаёт вызывающий (OQ-157)
|
||||
session: AsyncSession,
|
||||
audit: AuditService,
|
||||
*,
|
||||
document: Document,
|
||||
user_id: uuid.UUID,
|
||||
changed_by: uuid.UUID | None,
|
||||
now: datetime.datetime,
|
||||
comment: str | None = None,
|
||||
) -> list[uuid.UUID]:
|
||||
"""Хук подтверждения (spec «Подтверждение документа»): привязывает уже `CONFIRMED` документ ко всем версиям «в
|
||||
работе», которым он подходит, заменяя привязанный документ того же ключа (R-1); версия из `INITIATED` /
|
||||
`DOCUMENTS_PROCESSING` переходит в `DATA_CORRECTION` (`changed_by = user_id`, D-6). Возвращает id версий,
|
||||
получивших привязку (по возрастанию).
|
||||
"""Хук подтверждения (spec «Подтверждение документа», osv-result-mapping «Автоподтверждение чистого документа»):
|
||||
привязывает уже `CONFIRMED` документ ко всем версиям «в работе», которым он подходит, заменяя привязанный документ
|
||||
того же ключа (R-1); версия из `INITIATED` / `DOCUMENTS_PROCESSING` переходит в `DATA_CORRECTION` с `changed_by` и
|
||||
`comment` вызывающего (ручное подтверждение — пользователь и `None`, автоподтверждение — загрузивший файл и
|
||||
«автоподтверждение документа …», D-2). `changed_by is None` (файл без `uploaded_by`) — привязка создаётся, переход
|
||||
пропускается с записью в лог (`consolidation_status_history.changed_by` NOT NULL). Возвращает id версий, получивших
|
||||
привязку (по возрастанию).
|
||||
|
||||
Вызывать после блокировки файла и документа (D-9): версии блокирует `repo.lock_versions_for_entity` — advisory ГК
|
||||
(создание версии ∥ подтверждение) и `FOR UPDATE` надмножества версий ГК (правка периметра ∥ подтверждение, R-2).
|
||||
@ -227,15 +231,23 @@ async def on_document_confirmed(
|
||||
continue
|
||||
await _bind(session, version.id, document)
|
||||
if version.status in MOVES_TO_CORRECTION:
|
||||
await transition(
|
||||
session,
|
||||
audit,
|
||||
version=version,
|
||||
to=ConsolidationStatus.DATA_CORRECTION,
|
||||
changed_by=user_id,
|
||||
comment=None,
|
||||
now=now,
|
||||
)
|
||||
if changed_by is None:
|
||||
logger.info(
|
||||
"Переход версии по подтверждению пропущен: нет автора (changed_by обязателен). "
|
||||
"version_id={version_id}, document_id={document_id}",
|
||||
version_id=version.id,
|
||||
document_id=document.id,
|
||||
)
|
||||
else:
|
||||
await transition(
|
||||
session,
|
||||
audit,
|
||||
version=version,
|
||||
to=ConsolidationStatus.DATA_CORRECTION,
|
||||
changed_by=changed_by,
|
||||
comment=comment,
|
||||
now=now,
|
||||
)
|
||||
bound.append(version.id)
|
||||
return bound
|
||||
|
||||
|
||||
@ -273,7 +273,7 @@ class DocumentService:
|
||||
meta.reviewed_at = now
|
||||
await self._session.flush()
|
||||
await consolidation_documents.on_document_confirmed(
|
||||
self._session, self._audit.service, document=document, user_id=self._audit.user_id, now=now
|
||||
self._session, self._audit.service, document=document, changed_by=self._audit.user_id, now=now
|
||||
)
|
||||
await self._audit.record(
|
||||
action=AuditAction.DOCUMENT_CONFIRM,
|
||||
|
||||
@ -473,7 +473,7 @@ async def test_on_document_confirmed_returns_bound_versions(seeded: AsyncSession
|
||||
user = await _user(seeded)
|
||||
|
||||
bound = await consolidation_documents.on_document_confirmed(
|
||||
seeded, AuditService(seeded), document=document, user_id=user.id, now=utc_now()
|
||||
seeded, AuditService(seeded), document=document, changed_by=user.id, now=utc_now()
|
||||
)
|
||||
|
||||
assert bound == sorted([q2.id, q3.id])
|
||||
@ -481,6 +481,49 @@ async def test_on_document_confirmed_returns_bound_versions(seeded: AsyncSession
|
||||
assert await _bound(seeded, q4.id) == set()
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
async def test_on_document_confirmed_without_changed_by_binds_but_keeps_status(seeded: AsyncSession) -> None:
|
||||
"""Автоподтверждение файла без `uploaded_by` (OQ-157, D-2): привязка есть, перехода версии нет."""
|
||||
group, entities = await _group(seeded)
|
||||
version = await _version(seeded, group, entities)
|
||||
document = await _confirmed(seeded, entities[0], quarter=Q2)
|
||||
history = len(await _history(seeded, version.id))
|
||||
|
||||
bound = await consolidation_documents.on_document_confirmed(
|
||||
seeded, AuditService(seeded), document=document, changed_by=None, now=utc_now()
|
||||
)
|
||||
|
||||
assert bound == [version.id]
|
||||
assert document.id in await _bound(seeded, version.id)
|
||||
assert await _status(seeded, version.id) is ConsolidationStatus.INITIATED
|
||||
assert len(await _history(seeded, version.id)) == history
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
async def test_on_document_confirmed_writes_comment_to_history(seeded: AsyncSession) -> None:
|
||||
"""Комментарий перехода от вызывающего (автоподтверждение) попадает в историю статусов."""
|
||||
group, entities = await _group(seeded)
|
||||
version = await _version(seeded, group, entities)
|
||||
user = await _user(seeded)
|
||||
document = await _confirmed(seeded, entities[0], quarter=Q2)
|
||||
|
||||
await consolidation_documents.on_document_confirmed(
|
||||
seeded,
|
||||
AuditService(seeded),
|
||||
document=document,
|
||||
changed_by=user.id,
|
||||
comment="автоподтверждение документа OSV 60",
|
||||
now=utc_now(),
|
||||
)
|
||||
|
||||
last = (await _history(seeded, version.id))[-1]
|
||||
assert (last.to_status, last.changed_by, last.comment) == (
|
||||
ConsolidationStatus.DATA_CORRECTION,
|
||||
user.id,
|
||||
"автоподтверждение документа OSV 60",
|
||||
)
|
||||
|
||||
|
||||
# --- подхват ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -700,7 +743,7 @@ async def _confirm_in(session: AsyncSession, data: dict[str, Any]) -> list[uuid.
|
||||
document.confirmed_at = now
|
||||
await session.flush()
|
||||
return await consolidation_documents.on_document_confirmed(
|
||||
session, AuditService(session), document=document, user_id=data["user_id"], now=now
|
||||
session, AuditService(session), document=document, changed_by=data["user_id"], now=now
|
||||
)
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user