Track-changes: read all docs for the review panel Overview and change authors (#262)

* track-changes: list ranges of all docs in the review panel Overview

GET /project/:project_id/ranges returned document-updater's
/project/:id/ranges, which only covers docs currently loaded in Redis.
Comments and tracked changes in any doc nobody had opened since it was
last unloaded (or since document-updater restarted) were missing from
the Overview tab until that file was opened.

Flush the project's loaded docs to docstore first (POST
/project/:id/flush writes them back without unloading them), then read
the ranges of all non-deleted docs from docstore. After the flush
docstore is complete and current, so there is nothing to merge; this is
simpler than overlaying document-updater's live ranges on docstore's.
The response keeps the shape the frontend decodes ([{ id, ranges }]),
and docs without ranges get {} as document-updater returned for them.

The flush makes the request cost proportional to the number of loaded
docs with unflushed changes, and docstore unarchives the project's docs
if they were archived; on very large projects opening the Overview may
therefore be slower than before.

* track-changes: flush before listing tracked change authors

getChangesUsers read docstore directly. A tracked change still in
document-updater (not yet flushed to Mongo) was not seen, so the review
panel could not name its author once they left the project. Flush the
project first, as getAllRanges does since the previous commit.

Reported in ayaka-notes/ayakaleaf-pro#108.
This commit is contained in:
Tobias Hallmen
2026-11-04 14:12:27 +01:00
committed by GitHub
parent 21165d882e
commit 5b6154bcde
@@ -37,8 +37,11 @@ const TrackChangesController = {
async getAllRanges(req, res, next) {
try {
const { project_id } = req.params
const ranges = await DocumentUpdaterHandler.promises.getProjectRanges(project_id)
res.json(ranges)
// document-updater only knows the docs loaded in Redis. Flush them to
// docstore (without unloading) and read every non-deleted doc from there.
await DocumentUpdaterHandler.promises.flushProjectToMongo(project_id)
const docs = await DocstoreManager.promises.getAllRanges(project_id)
res.json(docs.map(doc => ({ id: doc._id, ranges: doc.ranges ?? {} })))
} catch (err) {
next(err)
}
@@ -50,6 +53,9 @@ const TrackChangesController = {
// provided here to assign names to authors who have left the project but still have unaccepted changes.
try {
const { project_id } = req.params
// Same as getAllRanges: a tracked change still in document-updater is
// not in docstore yet, so its author would be missing here.
await DocumentUpdaterHandler.promises.flushProjectToMongo(project_id)
const memberIds = await DocstoreManager.promises.getTrackedChangesUserIds(project_id)
const limit = pLimit(3)
const users = await Promise.all(