feat(vector): index files in real time on vector-index tag changes

Tagging an existing file/folder emits only OCP\SystemTag\MapperEvent — never a
Node*Event — so tagged PDFs were previously only picked up by the hourly
scanner. Subscribe to the tag event and reconcile membership so adding/removing
the `vector-index` tag (re)indexes in near-real time.

- webhook_presets: add OCP\SystemTag\MapperEvent to the files_sync preset
  (NC 32+, where MapperEvent gained getWebhookSerializable(); harmless on older
  servers — it just never fires).
- webhook_parser: parse MapperEvent (objectType=files) into a path-less file
  "reconcile" task. The payload carries only a fileid + tagIds (no name/path),
  so assign and unassign both collapse to a reconcile.
- processor._reconcile_tag_event: resolve the fileid against the user's current
  vector-index PDFs (find_files_by_tag). Present -> index with the resolved
  path/etag; absent -> flip to delete. Naturally handles "an unrelated tag
  changed" and a tagged folder's own fileid (no-op; the scanner still expands
  folders to descendants).
- Unit tests for the parser branch and the reconcile.

The matching admin-UI preset change ships separately in the astrolabe app repo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-06-05 16:20:05 +02:00
co-authored by Claude Opus 4.8
parent 78f3f284a6
commit 1322e5aba0
6 changed files with 313 additions and 4 deletions
+15 -1
View File
@@ -30,6 +30,13 @@ FILE_EVENT_WRITTEN = "OCP\\Files\\Events\\Node\\NodeWrittenEvent"
# See: https://github.com/nextcloud/server/issues/56371
FILE_EVENT_DELETED = "OCP\\Files\\Events\\Node\\BeforeNodeDeletedEvent"
# System-tag assign/unassign (Nextcloud 32+). A single event class covers both
# directions; the payload's ``eventType`` distinguishes them. Lets adding/removing
# the ``vector-index`` tag trigger near-real-time (re)indexing instead of waiting
# for the hourly scan. Requires NC >= 32 — MapperEvent gained
# getWebhookSerializable() in 32.0.0; on older servers the event isn't delivered.
SYSTEMTAG_EVENT_MAPPER = "OCP\\SystemTag\\MapperEvent"
# Calendar webhook events
CALENDAR_EVENT_CREATED = "OCP\\Calendar\\Events\\CalendarObjectCreatedEvent"
CALENDAR_EVENT_UPDATED = "OCP\\Calendar\\Events\\CalendarObjectUpdatedEvent"
@@ -128,7 +135,7 @@ WEBHOOK_PRESETS: Dict[str, WebhookPreset] = {
},
"files_sync": {
"name": "All Files Sync",
"description": "Real-time synchronization for all file operations (create, update, delete)",
"description": "Real-time synchronization for all file operations (create, update, delete) and tag changes (Nextcloud 32+)",
"app": "files",
"events": [
{
@@ -143,6 +150,13 @@ WEBHOOK_PRESETS: Dict[str, WebhookPreset] = {
"event": FILE_EVENT_DELETED,
"filter": {},
},
# Tag assign/unassign. Drives vector-index (re)indexing when a file
# or folder is tagged/untagged. Delivered only on NC >= 32; harmless
# to register on older servers (the event simply never fires).
{
"event": SYSTEMTAG_EVENT_MAPPER,
"filter": {},
},
],
},
"deck_sync": {