🐛(backend) create a link_trace record for onboarded documents

When a user is created, we created accesses to a list of onboarding
documents. Doing this have side effect on the proximity search feature.
Instead of creating access, we should create link_reach
This commit is contained in:
Manuel Raynaud
2026-03-12 13:51:41 +01:00
parent 6d73fb69b0
commit e36366b293
4 changed files with 58 additions and 41 deletions
+4
View File
@@ -13,6 +13,10 @@ and this project adheres to
- ♿(frontend) localize LaGaufre label fallback in Docs #1979
### Fixed
- 🐛(backend) create a link_trace record for on-boarding documents
## [v4.7.0] - 2026-03-09
### Added
+11 -8
View File
@@ -227,11 +227,11 @@ class User(AbstractBaseUser, BaseModel, auth_models.PermissionsMixin):
def _handle_onboarding_documents_access(self):
"""
If the user is new and there are documents configured to be given to new users,
give access to these documents and pin them as favorites for the user.
create link traces to these documents and pin them as favorites for the user.
"""
if settings.USER_ONBOARDING_DOCUMENTS:
onboarding_document_ids = set(settings.USER_ONBOARDING_DOCUMENTS)
onboarding_accesses = []
onboarding_link_traces = []
favorite_documents = []
for document_id in onboarding_document_ids:
try:
@@ -243,16 +243,20 @@ class User(AbstractBaseUser, BaseModel, auth_models.PermissionsMixin):
)
continue
onboarding_accesses.append(
DocumentAccess(
user=self, document=document, role=RoleChoices.READER
if document.link_reach == LinkReachChoices.RESTRICTED:
logger.warning(
"Onboarding on a restricted document is not allowed. Must be public or "
"connected. Restricted document: %s",
document_id,
)
)
continue
onboarding_link_traces.append(LinkTrace(user=self, document=document))
favorite_documents.append(
DocumentFavorite(user=self, document_id=document_id)
)
DocumentAccess.objects.bulk_create(onboarding_accesses)
LinkTrace.objects.bulk_create(onboarding_link_traces)
DocumentFavorite.objects.bulk_create(favorite_documents)
def _duplicate_onboarding_sandbox_document(self):
@@ -264,7 +268,6 @@ class User(AbstractBaseUser, BaseModel, auth_models.PermissionsMixin):
sandbox_id = settings.USER_ONBOARDING_SANDBOX_DOCUMENT
try:
template_document = Document.objects.get(id=sandbox_id)
except Document.DoesNotExist:
logger.warning(
"Onboarding sandbox document with id %s does not exist. Skipping.",
@@ -79,7 +79,7 @@ def test_models_invitations_is_expired():
assert expired_invitation.is_expired is True
def test_models_invitationd_new_userd_convert_invitations_to_accesses():
def test_models_invitations_new_user_convert_invitations_to_accesses():
"""
Upon creating a new user, invitations linked to the email
should be converted to accesses and then deleted.
+42 -32
View File
@@ -89,24 +89,19 @@ def test_models_users_handle_onboarding_documents_access_empty_setting():
assert models.DocumentAccess.objects.filter(user=user).count() == 0
def test_models_users_handle_onboarding_documents_access_with_single_document():
def test_models_users_handle_onboarding_document_link_trace_with_single_document():
"""
When USER_ONBOARDING_DOCUMENTS has a valid document ID,
an access should be created for the new user with the READER role.
a LinkTrace should be created for the new user.
The document should be pinned as a favorite for the user.
"""
document = factories.DocumentFactory()
document = factories.DocumentFactory(link_reach=models.LinkReachChoices.PUBLIC)
with override_settings(USER_ONBOARDING_DOCUMENTS=[str(document.id)]):
user = factories.UserFactory()
assert (
models.DocumentAccess.objects.filter(user=user, document=document).count() == 1
)
access = models.DocumentAccess.objects.get(user=user, document=document)
assert access.role == models.RoleChoices.READER
assert models.LinkTrace.objects.filter(user=user, document=document).count() == 1
user_favorites = models.DocumentFavorite.objects.filter(user=user)
assert user_favorites.count() == 1
@@ -121,9 +116,15 @@ def test_models_users_handle_onboarding_documents_access_with_multiple_documents
All accesses should have the READER role.
All documents should be pinned as favorites for the user.
"""
document1 = factories.DocumentFactory(title="Document 1")
document2 = factories.DocumentFactory(title="Document 2")
document3 = factories.DocumentFactory(title="Document 3")
document1 = factories.DocumentFactory(
title="Document 1", link_reach=models.LinkReachChoices.PUBLIC
)
document2 = factories.DocumentFactory(
title="Document 2", link_reach=models.LinkReachChoices.AUTHENTICATED
)
document3 = factories.DocumentFactory(
title="Document 3", link_reach=models.LinkReachChoices.PUBLIC
)
with override_settings(
USER_ONBOARDING_DOCUMENTS=[
@@ -134,15 +135,12 @@ def test_models_users_handle_onboarding_documents_access_with_multiple_documents
):
user = factories.UserFactory()
user_accesses = models.DocumentAccess.objects.filter(user=user)
assert user_accesses.count() == 3
link_traces = models.LinkTrace.objects.filter(user=user)
assert link_traces.count() == 3
assert models.DocumentAccess.objects.filter(user=user, document=document1).exists()
assert models.DocumentAccess.objects.filter(user=user, document=document2).exists()
assert models.DocumentAccess.objects.filter(user=user, document=document3).exists()
for access in user_accesses:
assert access.role == models.RoleChoices.READER
assert models.LinkTrace.objects.filter(user=user, document=document1).exists()
assert models.LinkTrace.objects.filter(user=user, document=document2).exists()
assert models.LinkTrace.objects.filter(user=user, document=document3).exists()
user_favorites = models.DocumentFavorite.objects.filter(user=user)
assert user_favorites.count() == 3
@@ -166,7 +164,7 @@ def test_models_users_handle_onboarding_documents_access_with_invalid_document_i
call_args = mock_logger.warning.call_args
assert "Onboarding document with id" in call_args[0][0]
assert models.DocumentAccess.objects.filter(user=user).count() == 0
assert models.LinkTrace.objects.filter(user=user).count() == 0
def test_models_users_handle_onboarding_documents_access_duplicate_prevention():
@@ -174,16 +172,27 @@ def test_models_users_handle_onboarding_documents_access_duplicate_prevention():
If the same document is listed multiple times in USER_ONBOARDING_DOCUMENTS,
it should only create one access (or handle duplicates gracefully).
"""
document = factories.DocumentFactory()
document = factories.DocumentFactory(link_reach=models.LinkReachChoices.PUBLIC)
with override_settings(
USER_ONBOARDING_DOCUMENTS=[str(document.id), str(document.id)]
):
user = factories.UserFactory()
user_accesses = models.DocumentAccess.objects.filter(user=user, document=document)
link_traces = models.LinkTrace.objects.filter(user=user, document=document)
assert user_accesses.count() >= 1
assert link_traces.count() == 1
def test_models_users_handle_onboarding_documents_on_restricted_document_is_not_allowed():
"""On-boarding document can be used when restricted"""
document = factories.DocumentFactory(link_reach=models.LinkReachChoices.RESTRICTED)
settings.USER_ONBOARDING_DOCUMENTS = [str(document.id)]
user = factories.UserFactory()
assert not models.LinkTrace.objects.filter(user=user, document=document).exists()
@override_settings(USER_ONBOARDING_SANDBOX_DOCUMENT=None)
@@ -272,7 +281,9 @@ def test_models_users_duplicate_onboarding_sandbox_document_integration_with_oth
Verify that sandbox creation works alongside other onboarding methods.
"""
template_document = factories.DocumentFactory(title="Getting started with Docs")
onboarding_doc = factories.DocumentFactory(title="Onboarding Document")
onboarding_doc = factories.DocumentFactory(
title="Onboarding Document", link_reach=models.LinkReachChoices.AUTHENTICATED
)
with override_settings(
USER_ONBOARDING_SANDBOX_DOCUMENT=str(template_document.id),
@@ -284,11 +295,10 @@ def test_models_users_duplicate_onboarding_sandbox_document_integration_with_oth
creator=user, title="Getting started with Docs"
).first()
user_accesses = models.DocumentAccess.objects.filter(user=user)
assert user_accesses.count() == 2
assert models.DocumentAccess.objects.filter(user=user).count() == 1
assert models.LinkTrace.objects.filter(user=user).count() == 1
sandbox_access = user_accesses.get(document=sandbox_doc)
onboarding_access = user_accesses.get(document=onboarding_doc)
assert sandbox_access.role == models.RoleChoices.OWNER
assert onboarding_access.role == models.RoleChoices.READER
assert models.DocumentAccess.objects.filter(
document=sandbox_doc, user=user, role=models.RoleChoices.OWNER
).exists()
assert models.LinkTrace.objects.filter(document=onboarding_doc, user=user).exists()