Git-Repository für bestehenden archivdms-Code initialisiert, Branch-/Commit-Konvention (feature/<ticket>-<slug>-Branches, Ticket-Prefix in Commit-Nachricht) etabliert.
56 lines
3.0 KiB
SQL
56 lines
3.0 KiB
SQL
-- PROJ: ML-Retraining-Klassifizierung Phase 1 (Naive-Bayes)
|
|
-- Doku-only (siehe README.md in diesem Verzeichnis) — die tatsächliche
|
|
-- Ausführung passiert idempotent über
|
|
-- internal/storage/ml_classifier.go (*Store).initMLClassifierSchema(),
|
|
-- eingehängt in internal/storage/documents.go (*Store).initSchema() NACH
|
|
-- initTaxonomySchema (setzt document_types/correspondents/tags/document_tags/
|
|
-- documents voraus).
|
|
--
|
|
-- Ergänzt die bestehende Regel-Engine (Taxonomie-Matching) um ein optionales,
|
|
-- pro Mandant trainiertes Naive-Bayes-Modell: aus bereits klassifizierten
|
|
-- Dokumenten werden Token-Häufigkeiten je Klasse (document_type/correspondent/
|
|
-- tag) gelernt (ml_classifier_tokens/ml_classifier_classes) und je Trainingslauf
|
|
-- protokolliert (ml_classifier_runs).
|
|
--
|
|
-- Provenienz-Spalten (assigned_via auf document_tags, doc_type_assigned_via/
|
|
-- correspondent_assigned_via auf documents) unterscheiden 'manual' (Nutzer
|
|
-- hat gesetzt), 'rule' (Regel-Engine) und 'ml_accepted' (vom Klassifizierer
|
|
-- vorgeschlagen und vom Nutzer akzeptiert). DEFAULT 'manual' bewusst konservativ
|
|
-- gewählt: bestehende Zeilen werden NICHT rückwirkend als 'rule' fehlklassifiziert
|
|
-- und fließen dadurch weiterhin normal als Trainingsdaten in den Klassifizierer ein.
|
|
|
|
CREATE TABLE IF NOT EXISTS ml_classifier_tokens (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
tenant_id BIGINT NOT NULL,
|
|
kind TEXT NOT NULL CHECK (kind IN ('document_types','correspondents','tags')),
|
|
entity_id BIGINT NOT NULL,
|
|
token TEXT NOT NULL,
|
|
count BIGINT NOT NULL DEFAULT 0,
|
|
UNIQUE (tenant_id, kind, entity_id, token)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_ml_tokens_lookup ON ml_classifier_tokens(tenant_id, kind, token);
|
|
|
|
CREATE TABLE IF NOT EXISTS ml_classifier_classes (
|
|
tenant_id BIGINT NOT NULL,
|
|
kind TEXT NOT NULL,
|
|
entity_id BIGINT NOT NULL,
|
|
doc_count BIGINT NOT NULL DEFAULT 0,
|
|
total_tokens BIGINT NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (tenant_id, kind, entity_id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS ml_classifier_runs (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
tenant_id BIGINT NOT NULL,
|
|
started_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
completed_at TIMESTAMPTZ,
|
|
doc_count BIGINT NOT NULL DEFAULT 0,
|
|
status TEXT NOT NULL DEFAULT 'running' CHECK (status IN ('running','completed','failed','skipped_insufficient_data')),
|
|
error TEXT
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_ml_classifier_runs_tenant ON ml_classifier_runs(tenant_id);
|
|
|
|
ALTER TABLE document_tags ADD COLUMN IF NOT EXISTS assigned_via TEXT NOT NULL DEFAULT 'manual' CHECK (assigned_via IN ('manual','rule','ml_accepted'));
|
|
ALTER TABLE documents ADD COLUMN IF NOT EXISTS doc_type_assigned_via TEXT NOT NULL DEFAULT 'manual' CHECK (doc_type_assigned_via IN ('manual','rule','ml_accepted'));
|
|
ALTER TABLE documents ADD COLUMN IF NOT EXISTS correspondent_assigned_via TEXT NOT NULL DEFAULT 'manual' CHECK (correspondent_assigned_via IN ('manual','rule','ml_accepted'));
|