Datenbankschema
Snoopy verwendet eine lokale SQLite-Datenbank.
Speicherort
Pfadmuster:
<rootDir>/snoopy.db
Standard-Stammverzeichnis ist <home>/.snoopy auf allen unterstützten Betriebssystemen:
- macOS-Beispiel:
~/.snoopy/snoopy.db - Linux-Beispiel:
~/.snoopy/snoopy.db - Windows-Beispiel:
C:\Users\<Sie>\.snoopy\snoopy.db
Standardpfad (macOS/Linux):
~/.snoopy/snoopy.db
Stammverzeichnis überschreiben:
- Setzen Sie
SNOOPY_ROOT_DIR
Dann wird der DB-Pfad:
<SNOOPY_ROOT_DIR>/snoopy.db
Schemaquellen
- TypeScript-Migrationsmodule in
src/services/db/migrations/ - Migrations-Runner in
src/services/db/migrations/runner.ts - Datenbank-Bootstrap in
src/services/db/sqlite.ts(nur WAL-Modus + Runner-Aufruf)
Tabellen
settings
Zweck:
- Speichert Schlüssel-Wert-App-Einstellungen und Anmeldedaten-Metadaten
Spalten:
key TEXT PRIMARY KEYvalue TEXT NOT NULLupdated_at TEXT NOT NULL DEFAULT datetime('now')
Häufige Schlüssel:
modelmodel_settings_jsonreddit_app_namereddit_client_id
jobs
Zweck:
- Definiert Überwachungsjobs
Spalten:
id TEXT PRIMARY KEYslug TEXT UNIQUEname TEXT NOT NULL UNIQUEdescription TEXT NOT NULLqualification_prompt TEXT NOT NULLsubreddits_json TEXT NOT NULLschedule_cron TEXT NOT NULL DEFAULT '*/30 * * * *'enabled INTEGER NOT NULL DEFAULT 1monitor_comments INTEGER NOT NULL DEFAULT 1created_at TEXT NOT NULL DEFAULT datetime('now')updated_at TEXT NOT NULL DEFAULT datetime('now')
Indizes:
idx_jobs_slugeindeutiger Index aufslug
Hinweise:
- Befehle akzeptieren Job-ID oder Slug.
- Slugs werden in der Repository-Logik generiert und eindeutig gemacht.
job_runs
Zweck:
- Speichert jeden geplanten/manuellen Ausführungsversuch
Spalten im aktiven Laufzeit-Schema:
id TEXT PRIMARY KEYjob_id TEXT NOT NULL(FK zujobs.id)status TEXT NOT NULL(running,completed,failed,skipped)message TEXTstarted_at TEXTfinished_at TEXTitems_discovered INTEGER NOT NULL DEFAULT 0items_new INTEGER NOT NULL DEFAULT 0items_qualified INTEGER NOT NULL DEFAULT 0prompt_tokens INTEGER NOT NULL DEFAULT 0completion_tokens INTEGER NOT NULL DEFAULT 0estimated_cost_usd REALlog_file_path TEXTcreated_at TEXT NOT NULL DEFAULT datetime('now')
Hinweise:
- Migration 001 initialisiert eine minimale Version.
- Runtime-Bootstrap aktualisiert ältere lokale DBs durch Hinzufügen neuerer Analyse-Spalten.
log_file_pathverweist auf die protokollierte Laufdatei unter~/.snoopy/logs/, wenn detaillierte Protokollierung verfügbar ist.idx_job_runs_active_joberzwingt höchstens einerunning-Zeile projob_id, um überlappende Läufe zu verhindern.
scan_items
Zweck:
- Deduplizierter Speicher gescannter Beiträge/Kommentare und Qualifizierungsergebnis
- Unterstützt eine leichte Ergebnislebenszyklusverfolgung für nachgelagerte Automatisierung
Spalten:
id TEXT PRIMARY KEYjob_id TEXT NOT NULL(FK zujobs.id)run_id TEXT NOT NULL(FK zujob_runs.id)type TEXT NOT NULL CHECK(type IN ('post','comment'))reddit_post_id TEXT NOT NULLreddit_comment_id TEXTsubreddit TEXT NOT NULLauthor TEXT NOT NULLtitle TEXTbody TEXT NOT NULLurl TEXT NOT NULLreddit_posted_at TEXT NOT NULLqualified INTEGER NOT NULL DEFAULT 0viewed INTEGER NOT NULL DEFAULT 0validated INTEGER NOT NULL DEFAULT 0processed INTEGER NOT NULL DEFAULT 0consumed INTEGER NOT NULL DEFAULT 0qualification_reason TEXTcreated_at TEXT NOT NULL DEFAULT datetime('now')
Indizes:
idx_scan_items_dedupeindeutiger Index auf(job_id, reddit_post_id, COALESCE(reddit_comment_id,''))idx_scan_items_consumedIndex auf(job_id, qualified, consumed, created_at DESC)
Verhalten:
- Verhindert die erneute Verarbeitung desselben Beitrags/Kommentars pro Job
- Speichert den endgültigen Qualifizierungsgrund zur Nachprüfbarkeit
- Lebenszyklus-Flag-Semantik:
viewed = 1Ergebnis wurde von einem Operator oder Agenten überprüftvalidated = 1Ergebnis wurde qualitätsgeprüft/akzeptiertprocessed = 1Ergebnis wurde an nachgelagerten Workflow übergebenconsumed = 1Ergebnis wurde vomconsume-Befehl zurückgegeben und erscheint nicht mehr
Hinweise:
- SQLite speichert Booleans als Ganzzahlen (
0falsch,1wahr). - Neuere Laufzeitversionen füllen fehlende Lebenszyklus-Spalten beim Start mit
ALTER TABLEfür ältere lokale DBs nach.
daemon_state
Zweck:
- Reservierte Laufzeit-Zustandstabelle für den Daemon-Lebenszyklus
Spalten:
id INTEGER PRIMARY KEY CHECK (id = 1)is_running INTEGER NOT NULLupdated_at TEXT NOT NULL DEFAULT datetime('now')
migrations
Zweck:
- Verfolgt, welche Schema-Migrations vom Migrations-Runner angewendet wurden
Spalten:
id INTEGER PRIMARY KEYname TEXT NOT NULLapplied_at TEXT NOT NULL DEFAULT datetime('now')
Hinweise:
- Wird vom Migrations-Runner beim ersten DB-Zugriff automatisch erstellt
- Jede Zeile stellt ein angewendetes Migrationsmodul dar
snoopy doctormeldet ausstehende vs. angewendete Migrationen
Löschung und Daten-Lebenszyklus
Das Löschen eines Jobs über CLI/Repository entfernt:
scan_items-Zeilen für den Jobjob_runs-Zeilen für den Job- Zugehörige Laufprotokolldateien, auf die von
job_runs.log_file_pathverwiesen wird (wenn vorhanden) jobs-Zeile selbst
Diese Löschung wird in einer DB-Transaktion in der Repository-Logik ausgeführt.
Anfragebeispiele
Neueste Läufe für einen Job:
SELECT *
FROM job_runs
WHERE job_id = ?
ORDER BY created_at DESC
LIMIT 20;
Neueste qualifizierte Elemente für einen Lauf:
SELECT reddit_post_id, reddit_comment_id, qualified, qualification_reason
FROM scan_items
WHERE run_id = ?
ORDER BY created_at DESC;
Unverarbeitete qualifizierte Elemente für einen Job:
SELECT
id,
url,
author,
title,
qualification_reason,
viewed,
validated,
processed,
reddit_posted_at
FROM scan_items
WHERE job_id = ?
AND qualified = 1
AND processed = 0
ORDER BY datetime(reddit_posted_at) DESC;
Ein Ergebnis als überprüft + validiert markieren:
UPDATE scan_items
SET viewed = 1,
validated = 1
WHERE id = ?;
Qualifizierte Ergebnisse eines Laufs als verarbeitet markieren:
UPDATE scan_items
SET processed = 1
WHERE run_id = ?
AND qualified = 1;
Agenten-Workflow-Referenz
Für End-to-End-direkte DB-Workflows (Jobs auflisten, Jobs einfügen, Daemon-/Startzustand überprüfen, Jobs ausführen, Ergebnisse lesen/aktualisieren) siehe Agenten-Operationen.