Skip to content

✨(backend) manage reconciliation requests for user accounts#1708

Open
Ash-Crow wants to merge 14 commits intomainfrom
sbl/user-reconciliation
Open

✨(backend) manage reconciliation requests for user accounts#1708
Ash-Crow wants to merge 14 commits intomainfrom
sbl/user-reconciliation

Conversation

@Ash-Crow
Copy link
Collaborator

@Ash-Crow Ash-Crow commented Dec 8, 2025

Purpose

Fix #1616.

For now, the reconciliation requests are imported through CSV in the Django admin, which sends confirmation email to both addresses. When both are checked, the actual reconciliation is processed, in a threefold process (update document acess, update invitations, update user status.)

Proposal

  • New UserReconciliationCsvImport model to manage the import of reconciliation requests through a task (user_reconciliation_csv_import_job)
  • New UserReconciliation model to store the user reconciliation requests themselves (a row = a active_user/inactive_user pair)
    • On save, a confirmation email is sent to the users
  • A process_reconciliation admin action process the action on the requested entries, if both emails have been checked.
    • Bulk update the DocumentAccess items, while managing the case where both users have access to the document (keeping the higher role)
    • Bulk update the LinkTrace items, while managing the case where both users have link traces to the document
    • Bulk update the DocumentFavorite items, while managing the case where both users have put the document in their favorites
    • Bulk update the comment system items (Thread, Comment and Reaction items)
    • Bulk update the is_active status on both users
  • New USER_RECONCILIATION_FORM_URL env variable for the "make a new request" URL in an email.
  • Write unit tests

Demo page reconciliation success

In waiting for @rl-83 to provide the design:
image

@Ash-Crow Ash-Crow force-pushed the sbl/user-reconciliation branch 4 times, most recently from 4d4bd60 to ab55e01 Compare December 11, 2025 08:28
@Ash-Crow Ash-Crow requested review from lunika and removed request for lunika December 15, 2025 09:12
@Ash-Crow Ash-Crow force-pushed the sbl/user-reconciliation branch 11 times, most recently from 35c4d49 to 5090839 Compare December 15, 2025 21:49
@Ash-Crow Ash-Crow force-pushed the sbl/user-reconciliation branch 8 times, most recently from 47099e1 to 57050a1 Compare January 12, 2026 16:54
@AntoLC AntoLC force-pushed the sbl/user-reconciliation branch from 052b0b3 to d32ef62 Compare January 15, 2026 17:15
@lunika
Copy link
Member

lunika commented Jan 16, 2026

After discussion with @AntoLC some data migration are missing.
Other relations with the user exists in the database and this data will be lost if not transfered.
When a user visit a docs it doesn't have access (a public or connected one), an entry is added to the LinkTrace model. These docs will be shown to the user on its homepage. This table should also be migrated.
Same for the DocumentFavorite model. Should be migrated.

There are also relation with Thread, Comment and Reaction. But I don't know if they should be migrated. WDYT @virgile-dev @rl-83 ? A thread (the comment container) and comments should be migrated from the inactive user to the new one ?

Ash-Crow and others added 3 commits January 20, 2026 14:44
For now, the reconciliation requests are imported through CSV in the
Django admin, which sends confirmation email to both addresses.
When both are checked, the actual reconciliation is processed, in a
threefold process (update document acess, update invitations, update
user status.)
@Ash-Crow Ash-Crow force-pushed the sbl/user-reconciliation branch from d32ef62 to 032413a Compare January 20, 2026 13:45
@github-actions
Copy link

github-actions bot commented Jan 20, 2026

Size Change: +6.14 kB (+0.15%)

Total Size: 4.2 MB

Filename Size Change
apps/impress/out/_next/static/b7611922/_buildManifest.js 896 B +896 B (new file) 🆕
apps/impress/out/_next/static/chunks/3642.js 0 B -783 kB (removed) 🏆
apps/impress/out/_next/static/chunks/6605.js 780 kB +780 kB (new file) 🆕
apps/impress/out/_next/static/chunks/pages/_app.js 600 kB +5.11 kB (+0.86%)
apps/impress/out/_next/static/chunks/pages/user-reconciliations/active/[id].js 1.42 kB +1.42 kB (new file) 🆕
apps/impress/out/_next/static/chunks/pages/user-reconciliations/inactive/[id].js 1.42 kB +1.42 kB (new file) 🆕
apps/impress/out/_next/static/d33b0515/_buildManifest.js 0 B -831 B (removed) 🏆
apps/impress/out/user-reconciliations/active/[id]/index.html 1.23 kB +1.23 kB (new file) 🆕
apps/impress/out/user-reconciliations/inactive/[id]/index.html 1.23 kB +1.23 kB (new file) 🆕

compressed-size-action

This changes the way the reconciliation requests CSV imports are
processed and requires the CSV to provide a unique id for each
request.

Rows with errors are also now handled better so that they don't
fail the whole import.
This changes the way the reconciliation requests CSV imports are
processed and requires the CSV to provide a unique id for each
request.

Rows with errors are also now handled better so that they don't
fail the whole import.
This removes the new email template in favor of using the already
existing one, by removing the extra formating.
@Ash-Crow Ash-Crow force-pushed the sbl/user-reconciliation branch from 0d2b538 to c65ab34 Compare February 2, 2026 17:18
Process each reconciliation requests individually as a transaction,
with the bulk updates/deletes made for each requests, to avoid
interference between requests and unwanted states
Adds management of link traces and documents favorites in the reconciliation
requests.
@Ash-Crow
Copy link
Collaborator Author

Ash-Crow commented Feb 3, 2026

After discussion with @AntoLC some data migration are missing. Other relations with the user exists in the database and this data will be lost if not transfered. When a user visit a docs it doesn't have access (a public or connected one), an entry is added to the LinkTrace model. These docs will be shown to the user on its homepage. This table should also be migrated. Same for the DocumentFavorite model. Should be migrated.

Done.

There are also relation with Thread, Comment and Reaction. But I don't know if they should be migrated. WDYT @virgile-dev @rl-83 ? A thread (the comment container) and comments should be migrated from the inactive user to the new one ?

Done as well, if not needed we can put it behind a toggle controlled by an env variable.

@Ash-Crow Ash-Crow force-pushed the sbl/user-reconciliation branch from cb97eee to 1dc375e Compare February 3, 2026 18:57
Adds management of threads, comments and reactions in the
reconciliation requests.
@Ash-Crow Ash-Crow force-pushed the sbl/user-reconciliation branch from 1dc375e to b3e69ea Compare February 4, 2026 08:50
@Ash-Crow Ash-Crow marked this pull request as ready for review February 4, 2026 09:27
@Ash-Crow Ash-Crow force-pushed the sbl/user-reconciliation branch from 9784cce to 7e36d91 Compare February 4, 2026 09:33
This adds unit tests for the new API view that is used when a confirmation
link is clicked in an email.
@Ash-Crow Ash-Crow force-pushed the sbl/user-reconciliation branch from 7e36d91 to 2a8e51a Compare February 4, 2026 09:49
@Ash-Crow Ash-Crow requested review from AntoLC and lunika February 4, 2026 09:54
Copy link
Member

@lunika lunika left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few nitepicking otherwise it's good to me

from rest_framework import filters, status, viewsets
from rest_framework import response as drf_response
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line 41 the drf reponse module is imported, you can probably use it instead of making an other import ?

"""Generate and send email to the user from a template."""
emails = [self.email]
context = context or {}
domain = Site.objects.get_current().domain
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should do like in this PR : #1825

Copy link
Member

@lunika lunika left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't saw you have merge commits in your commits history.
You have to remove them

- ✨(helm) redirecting system #1697
- 📱(frontend) add comments for smaller device #1737
- ✨(project) add custom js support via config #1759
- ✨(backend) manage reconciliation requests for user accounts #1708
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be placed under "Unreleased"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a front route for user reconciliations Handle users with multiple accounts

3 participants