Fix: bulk reprocess latest version for root documents

This commit is contained in:
shamoon committed 2026-10-07 16:14:36 -07:00
1 parent d7a9894400
commit 702c5561d4
4 files changed
+137 -5

No files matched your search

+8 -2
View File
@@ -408,10 +408,16 @@ def reprocess(doc_ids: list[int], *, remote_ocr: bool = False) -> Literal["OK"]:
Consumption workflows do not run here, so ``remote_ocr`` is how the user
asks for the remote engine when it is not configured to handle everything.
A root document with versions reprocesses its latest version, which is the
file whose content, archive and thumbnail are shown for it.
"""
for document_id in doc_ids:
for doc in Document.objects.select_related("root_document").filter(
id__in=doc_ids,
):
pair = _resolve_root_and_source_doc(doc)
update_document_content_maybe_archive_file.apply_async(
kwargs={"document_id": document_id, "remote_ocr": remote_ocr},
kwargs={"document_id": pair.source_doc.id, "remote_ocr": remote_ocr},
headers={"trigger_source": PaperlessTask.TriggerSource.MANUAL},
)
+8 -3
View File
@@ -490,18 +490,23 @@ def update_document_content_maybe_archive_file(
shutil.move(thumbnail, document.thumbnail_path)
document.refresh_from_db()
root_document = (
document.root_document if document.root_document_id else document
)
logger.info(
f"Updating index for document {document_id} ({document.archive_checksum})",
f"Updating index for document {root_document.pk} ({document.archive_checksum})",
)
from documents.search import get_backend
get_backend().add_or_update(document)
get_backend().add_or_update(root_document)
ai_config = AIConfig()
if ai_config.llm_index_enabled:
llm_index_add_or_update_document(document)
llm_index_add_or_update_document(root_document)
clear_document_caches(document.pk)
if root_document.pk != document.pk:
clear_document_caches(root_document.pk)
except Exception:
logger.exception(
+66
View File
@@ -2021,3 +2021,69 @@ class TestBulkEditReprocess(DirectoriesMixin, TestCase):
self.assertEqual(mock_task.apply_async.call_count, 2)
for call in mock_task.apply_async.call_args_list:
self.assertTrue(call.kwargs["kwargs"]["remote_ocr"])
@mock.patch("documents.bulk_edit.update_document_content_maybe_archive_file")
def test_reprocess_root_uses_latest_version(self, mock_task: mock.Mock) -> None:
"""
GIVEN:
- A root document with two versions
WHEN:
- reprocess is called with the root document
THEN:
- The latest version is reprocessed, not the root's original file
"""
Document.objects.create(
title="test",
checksum="A-v1",
mime_type="application/pdf",
root_document=self.doc,
version_index=1,
)
latest = Document.objects.create(
title="test",
checksum="A-v2",
mime_type="application/pdf",
root_document=self.doc,
version_index=2,
)
bulk_edit.reprocess([self.doc.id])
mock_task.apply_async.assert_called_once()
self.assertEqual(
mock_task.apply_async.call_args.kwargs["kwargs"]["document_id"],
latest.id,
)
@mock.patch("documents.bulk_edit.update_document_content_maybe_archive_file")
def test_reprocess_explicit_version(self, mock_task: mock.Mock) -> None:
"""
GIVEN:
- A root document with two versions
WHEN:
- reprocess is called with the older version
THEN:
- That version is reprocessed
"""
older = Document.objects.create(
title="test",
checksum="A-v1",
mime_type="application/pdf",
root_document=self.doc,
version_index=1,
)
Document.objects.create(
title="test",
checksum="A-v2",
mime_type="application/pdf",
root_document=self.doc,
version_index=2,
)
bulk_edit.reprocess([older.id])
mock_task.apply_async.assert_called_once()
self.assertEqual(
mock_task.apply_async.call_args.kwargs["kwargs"]["document_id"],
older.id,
)
+55
View File
@@ -287,6 +287,61 @@ class TestUpdateContent(DirectoriesMixin, TestCase):
tasks.update_document_content_maybe_archive_file(doc.pk)
self.assertNotEqual(Document.objects.get(pk=doc.pk).content, "test")
@mock.patch("documents.tasks.clear_document_caches")
@mock.patch("documents.search.get_backend")
def test_update_content_version_indexes_root(
self,
mock_get_backend: mock.Mock,
mock_clear_caches: mock.Mock,
) -> None:
"""
GIVEN:
- A root document with a version
WHEN:
- Update content task is called for the version
THEN:
- The version's content is updated
- The root document is indexed rather than the version
- Caches are cleared for both
"""
sample1 = self.dirs.scratch_dir / "sample.pdf"
shutil.copy(
Path(__file__).parent
/ "samples"
/ "documents"
/ "originals"
/ "0000001.pdf",
sample1,
)
root = Document.objects.create(
title="test",
content="root content",
checksum="root",
mime_type="application/pdf",
)
version = Document.objects.create(
title="test",
content="my document",
checksum="wow",
filename=sample1,
mime_type="application/pdf",
root_document=root,
version_index=1,
)
tasks.update_document_content_maybe_archive_file(version.pk)
self.assertNotEqual(
Document.objects.get(pk=version.pk).content,
"my document",
)
self.assertEqual(Document.objects.get(pk=root.pk).content, "root content")
indexed = mock_get_backend.return_value.add_or_update.call_args.args[0]
self.assertEqual(indexed.pk, root.pk)
mock_clear_caches.assert_has_calls(
[mock.call(version.pk), mock.call(root.pk)],
)
class TestUpdateContentRemoteOCR(DirectoriesMixin, TestCase):
"""