docs: library indexing is scheduled and on request; panel note matches
All checks were successful
Forgejo Docker Build / Root app tests (push) Successful in 52s
Forgejo Docker Build / Build Docker image (push) Successful in 9s
Forgejo Docker Build / End-to-end (browser) (push) Successful in 5s

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
This commit is contained in:
Daniel 2026-09-13 16:34:16 +02:00
parent 34c495b5d8
commit e23d35a570
3 changed files with 14 additions and 11 deletions

View file

@ -207,18 +207,19 @@ Add or update tests when changing:
- model discovery or settings behavior.
## Library indexing runs when asked, not on a timer
## Library indexing: on a schedule, and on request
The clinical library lives in Nextcloud folders and is indexed by the
clinical-assist indexer. It used to rescan every five minutes; a scan that
also walked ten thousand news-feed items took half an hour, so the indexer was
never idle. It now reconciles once when it starts and then only when an admin
presses **Run indexing now** (Admin → Clinical Assistant → Library index).
clinical-assist indexer, which reconciles them every five minutes
(`VECTOR_SYNC_SCAN_INTERVAL`). A scan used to walk ten thousand news-feed
items too and took half an hour; the News and Deck passes are now off, so a
scan is the files and notes only. **Run indexing now** (Admin → Clinical
Assistant → Library index) asks for a scan without waiting for the timer.
A reconciliation lists the library folders, queues documents that are new or
whose modification time changed, and drops the index rows of documents that
are gone — after a second consecutive scan confirms the absence, so one
listing that happened to fail deletes nothing. Documents already indexed and
are gone — after the absence has persisted for one and a half scan
intervals, so one listing that happened to fail deletes nothing. Documents already indexed and
unchanged are not touched, and nothing is re-extracted.
The button calls `POST /api/v1/vector-sync/scan` on the indexer with a bearer
@ -231,8 +232,10 @@ settings are empty):
| `clinical_assistant.indexer_token` | `CLINICAL_ASSISTANT_INDEXER_TOKEN` | none — the button refuses without one |
The token must equal `VECTOR_SYNC_TRIGGER_TOKEN` in the indexer's environment.
On the indexer side the mode is `VECTOR_SYNC_ON_DEMAND=true`; `VECTOR_SYNC_SCAN_NEWS`
and `VECTOR_SYNC_SCAN_DECK` are `false` for a documents-only library. Under
On the indexer side `VECTOR_SYNC_SCAN_NEWS` and `VECTOR_SYNC_SCAN_DECK` are
`false` for a documents-only library; `VECTOR_SYNC_ON_DEMAND=true` would stop
the timer and leave only the button (deletions then need two consecutive
scans). Under
[lockdown](authentication.md#lockdown-the-admin-panel-as-view-only) the button
still works — it is an operation, not a setting — but the address and token
are read-only.

View file

@ -420,7 +420,7 @@
<button type="button" class="btn btn-secondary btn-sm" id="btn-assistant-index-now"><i class="fas fa-sync"></i> Run indexing now</button>
<button type="button" class="btn btn-link btn-sm" id="btn-assistant-index-refresh">Refresh status</button>
</div>
<span class="admin-note">Indexing no longer runs on a timer. This queues documents added or changed in the library folders, drops what has been removed (after a second scan confirms it), and leaves everything else alone.</span>
<span class="admin-note">The indexer reconciles the library folders on its own schedule; this asks for a scan right now. New and changed documents are queued, removed documents are dropped once a second scan confirms it, everything already indexed is left alone.</span>
<details style="margin-top:4px;">
<summary style="cursor:pointer;font-size:13px;">Indexer address and token</summary>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:6px;">

View file

@ -281,5 +281,5 @@ test('the library index button is an operation, allowed under lockdown, and the
assert.doesNotMatch(admin.slice(admin.indexOf("router.get('/config/library-index'"), admin.indexOf("router.post('/config/library-index/scan'")), /token: target\.token/, 'the status reply must not carry the token');
const js = read('public/js/admin/clinicalAssistant.js');
assert.match(js, /setValue\('assistant-indexer-token', ''\)/);
assert.match(read('docs/clinical-assistant.md'), /## Library indexing runs when asked/);
assert.match(read('docs/clinical-assistant.md'), /## Library indexing: on a schedule, and on request/);
});