🐛(backend) do not filter deleted docs for the owner in the tree view

Fixes the bug described in #1254 (Delete document request conflict)

In the tree request, deleted documents for
which the user is the owner are not filtered anymore.
This commit is contained in:
Sylvain Boissel 2026-03-24 15:09:42 +01:00
parent 0d09f761dc
commit d786e9703e
No known key found for this signature in database
3 changed files with 73 additions and 1 deletions

View file

@ -10,6 +10,10 @@ and this project adheres to
- 💄(frontend) improve comments highlights #1961
### Fixed
- 🐛(backend) do not filter deleted documents for the owner in the tree #2121
## [v4.8.3] - 2026-03-23
### Changed

View file

@ -1209,7 +1209,20 @@ class DocumentViewSet(
path__startswith=ancestor.path, depth=ancestor.depth + 1
)
children = self.queryset.filter(children_clause, deleted_at__isnull=True)
# Include deleted documents owned by the user, if any.
if request.user.is_authenticated:
owned_document_ids = models.DocumentAccess.objects.filter(
user=user,
role=models.RoleChoices.OWNER,
document__deleted_at__isnull=False,
).values("document_id")
children = self.queryset.filter(
children_clause,
db.Q(deleted_at__isnull=True) | db.Q(id__in=owned_document_ids),
)
else:
children = self.queryset.filter(children_clause, deleted_at__isnull=True)
queryset = (
ancestors.select_related("creator").filter(

View file

@ -1258,3 +1258,58 @@ def test_api_documents_tree_list_deleted_document_owner(django_assert_num_querie
assert content["children"][0][
"deleted_at"
] == child.ancestors_deleted_at.isoformat().replace("+00:00", "Z")
def test_api_documents_tree_deleted_child_visible_to_owner():
"""
A deleted child document should appear in the tree for users who are its direct owner,
even when they are not the owner of the parent.
"""
user = factories.UserFactory()
client = APIClient()
client.force_login(user)
parent = factories.DocumentFactory(link_reach="public")
owned_child = factories.DocumentFactory(parent=parent, users=[(user, "owner")])
other_child = factories.DocumentFactory(parent=parent)
owned_child.soft_delete()
owned_child.refresh_from_db()
response = client.get(f"/api/v1.0/documents/{parent.id!s}/tree/")
assert response.status_code == 200
content = response.json()
child_ids = [c["id"] for c in content["children"]]
assert str(owned_child.id) in child_ids
assert str(other_child.id) in child_ids
owned_child_data = next(
c for c in content["children"] if c["id"] == str(owned_child.id)
)
assert owned_child_data["deleted_at"] == owned_child.deleted_at.isoformat().replace(
"+00:00", "Z"
)
def test_api_documents_tree_deleted_child_hidden_from_non_owner():
"""
A deleted child document should not appear in the tree for users who are not its owner.
"""
user = factories.UserFactory()
client = APIClient()
client.force_login(user)
parent = factories.DocumentFactory(link_reach="public")
deleted_child = factories.DocumentFactory(parent=parent)
visible_child = factories.DocumentFactory(parent=parent)
deleted_child.soft_delete()
response = client.get(f"/api/v1.0/documents/{parent.id!s}/tree/")
assert response.status_code == 200
content = response.json()
child_ids = [c["id"] for c in content["children"]]
assert str(deleted_child.id) not in child_ids
assert str(visible_child.id) in child_ids