munin/internal/store/migrations/sqlite/006_search_log.sql
2026-10-19 10:13:56 +02:00

42 lines
2.5 KiB
SQL

-- Suchprotokoll: Was Agenten mit "recall" suchen und ob sie etwas finden.
--
-- ── Warum? ───────────────────────────────────────────────────────────────────
--
-- Ohne diese Zahlen lässt sich nicht beurteilen, ob die Suche gut genug ist.
-- Eine Suche ohne Treffer ist das deutlichste Zeichen: Entweder gibt es das
-- Wissen nicht — dann ist die Anfrage ein Hinweis, was fehlt — oder es steht
-- unter anderen Wörtern da. Beides will man sehen (AUSBAUSTUFEN.md 3.1).
--
-- ── Warum nicht im Zugriffsprotokoll (audit_events)? ─────────────────────────
--
-- Gesucht wird viel öfter als geschrieben. Im Zugriffsprotokoll würden die
-- Suchen die Schreibvorgänge zudecken, um die es dort geht. Außerdem enthält
-- eine Anfrage Inhalt („wie kommt man an das Passwort für …"), und Inhalt hat
-- eine kürzere Aufbewahrungsfrist verdient als die 90 Tage des Protokolls:
-- Die tägliche Aufräumaufgabe löscht Zeilen nach 30 Tagen
-- (store.SearchLogRetention).
--
-- ── Aufbau ───────────────────────────────────────────────────────────────────
--
-- Eine Zeile je recall-Aufruf. Bewusst ohne IP-Adresse und ohne Namen: Für
-- die Auswertung zählt, WAS gesucht wurde, nicht wer. api_key_id bleibt, damit
-- sich ein einzelner Agent mit auffälligem Verhalten eingrenzen lässt.
--
-- Die ID ist hier eine fortlaufende Zahl (INTEGER PRIMARY KEY) statt eines
-- Zufallswerts wie in den anderen Tabellen: Niemand verweist auf eine
-- einzelne Zeile, und eine Zahl ist beim Einfügen am billigsten.
--
-- Anders als das Zugriffsprotokoll hängt die Tabelle per Fremdschlüssel am
-- Projekt: Wird es gelöscht, verschwinden auch seine Anfragen. Sie sind Inhalt
-- des Projekts, kein Nachweis darüber, wer was getan hat.
CREATE TABLE search_log (
id INTEGER PRIMARY KEY,
ts TEXT NOT NULL,
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
api_key_id TEXT NOT NULL DEFAULT '',
query TEXT NOT NULL,
synonyms TEXT NOT NULL DEFAULT '', -- mit Komma getrennt, leer = keine
results INTEGER NOT NULL -- Zahl der ausgegebenen Treffer
);
CREATE INDEX idx_search_log_project ON search_log (project_id, ts);