FDN-01: repository & projektgerüst
Git-Repository für bestehenden archivdms-Code initialisiert, Branch-/Commit-Konvention (feature/<ticket>-<slug>-Branches, Ticket-Prefix in Commit-Nachricht) etabliert.
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
---
|
||||
name: project-ollama-integration-plan
|
||||
description: Plan für lokale Ollama-Anbindung (Metadaten-Vorschläge + OCR-Textkorrektur) in archivdms, Stand 2026-07-16
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
|
||||
Plan verabschiedet für Ollama-Integration (kein Code, nur Architektur), Ziel: lokales LLM für (1) Metadaten-Vorschläge als dritter Provider neben heuristic/anthropic, (2) nachträgliche OCR-Textkorrektur.
|
||||
|
||||
Kernentscheidungen:
|
||||
- Modell: `qwen2.5:1.5b-instruct-q4_K_M` (~1-1.2GB RAM), Eskalation auf 3B nur falls Qualität nicht reicht. Server hat nur 4GB RAM/4 Kerne/keine GPU.
|
||||
- systemd-Hardening: MemoryMax=2200M, CPUQuota=250%, OOMScoreAdjust=500, bindet nur an 127.0.0.1:11434.
|
||||
- OCR-Korrektur läuft NICHT automatisch im Upload-Pipeline (Ressourcenrisiko), sondern über manuellen Endpoint `POST /api/documents/{id}/correct-ocr-text`, analog zu bestehendem `/reprocess`-Muster.
|
||||
- GoBD: Original-OCR-Text (`ocr_text`) wird nie überschrieben, Korrektur landet in neuem Feld `ocr_text_corrected`, Audit-Log-Pflicht pro Korrekturlauf.
|
||||
- Provider-Fehlerverhalten: bei Ollama nicht erreichbar → Fehler an Frontend, KEIN stiller Fallback auf heuristic (Nachvollziehbarkeit, welcher Provider geantwortet hat).
|
||||
- Config-Pattern: `llm.ollama.enabled/base_url/model/timeout_seconds` in config.yml, no-op wenn disabled — exakt wie `index.manticore_dsn`-Pattern.
|
||||
- Pro-Tenant-Schalter bewusst NICHT gebaut (Tag 1) — Ollama läuft als ein Prozess pro Server, kein echtes Isolationsmodell dahinter, wäre nur Schein-Kontrolle. Erst bei echter Mandantentrennung mit unterschiedlichen Compliance-Anforderungen nachrüsten.
|
||||
- Reihenfolge: 1) Ollama-Server-Setup (devops-deploy), 2) Metadaten-Provider (backend-dev), 3) OCR-Korrektur-Endpoint (baut auf Client aus Schritt 2 auf, plus Migration für ocr_text_corrected-Spalte).
|
||||
|
||||
**Why:** User hat sich bewusst für kleines lokales Modell trotz 4GB-RAM-Warnung entschieden (GoBD/Datenschutz — Belege dürfen Server nicht verlassen), Provider-Abstraktion (`metadata_suggestions.provider`-Spalte) existierte schon konzeptionell aus früherer Session, nur `heuristic` war je gebaut.
|
||||
|
||||
**How to apply:** Wenn Umsetzung (backend-dev/devops-deploy) ansteht, diesen Plan als Grundlage nehmen, nicht neu verhandeln, außer der User ändert explizit etwas. Verwandt: [[project_archivdms_status]], [[project_nil_slice_json_pattern]].
|
||||
@@ -0,0 +1,4 @@
|
||||
- [Deskew-Vorverarbeitung](project_deskew_preprocessing.md) — ImageMagick `-deskew 40%` vor OSD-Rotation, Server-Paket `imagemagick` (nicht nur `-common`)
|
||||
- [Titel-Heuristik + OSD Rotate:0-Lücke](project_title_heuristic_and_osd_zero_rotate_gap.md) — Alnum-Ratio-Filter statt "längste Zeile", rotateForOSD prüft Konfidenz nicht bei degrees==0
|
||||
- [Deskew-Border-Trick negativ getestet](project_deskew_border_trick_tested_negative.md) — weißer Rand vor -deskew half nicht (Artefakt-Winkel), verworfen, nicht wieder vorschlagen
|
||||
- [Deskew-Deaktivierung für Fotos negativ getestet](project_deskew_disable_for_photos_tested_negative.md) — gemischt (Doc7 stark schlechter), verworfen; runTesseract() ist einziger Aufrufpfad, keine Foto/PDF-Pipeline-Trennung vorhanden
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: deskew-border-trick-tested-negative
|
||||
description: Weißer Rand vor -deskew (bordercolor/border+shave) getestet gegen eng zugeschnittene Handyfotos — hat NICHT geholfen, verworfen
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
|
||||
Getestet am 2026-07-18 (Tenant 3, Dokumente 3/4/5/7): `convert -bordercolor white -border 50x50 -deskew 40% -shave 50x50` als Fix für das Problem, dass ImageMagicks `-deskew` bei eng zugeschnittenen Handyfotos (kein sichtbarer Hintergrundrand) kein Schräglagenwinkel erkennt.
|
||||
|
||||
Ergebnis: negativ. Der gemeldete `angle_deg` sprang von exakt `0` (ohne Border) auf einen konstanten Wert `~0.00699...` — bei ALLEN vier Testdokumenten identisch, obwohl die Bilder unterschiedlich stark verkippt sind. Das ist kein echter erkannter Schräglagenwinkel, sondern ein Artefakt der künstlichen Randgeometrie selbst (ImageMagick misst offenbar die Kante des hinzugefügten Rands, nicht den Bildinhalt). OCR-Textqualität blieb unverändert schlecht/durchwachsen (z.B. "o@rvice-Stat ic" statt "Service-Station" bei Dok 5).
|
||||
|
||||
Code-Änderung in `deskewImage()` (internal/ocr/ocr.go) wurde verworfen, Server zurück auf Original-Deskew ohne Border-Trick deployt (Redeploy 2026-07-18 bestätigt: Backend+Frontend laufen).
|
||||
|
||||
**Why:** Bestätigt die ursprüngliche Diagnose aus [[project_ocr_inkonsistenz_deskew_osd]] (falls vorhanden) — der Deskew-Ansatz per ImageMagick-Hintergrundkante ist für rand-lose Handyfotos strukturell ungeeignet, auch mit künstlichem Rand.
|
||||
|
||||
**How to apply:** Bei künftigen Anfragen zu Schräglagenerkennung bei Handyfotos ohne Scan-Rand NICHT wieder den Border-Trick vorschlagen — stattdessen andere Ansätze evaluieren (z.B. Hough-Transform-basierte Texterkennungswinkel, `unpaper`, oder Tesseract-eigene OSD-Rotation als einzige Verlässlichkeitsquelle akzeptieren und Fine-Skew-Korrektur bei diesen Dokumenten aufgeben).
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
---
|
||||
name: deskew-disable-for-photos-tested-negative
|
||||
description: A/B-Test "deskewImage komplett weglassen, Tesseract-interne Skew-Korrektur wirken lassen" bei Foto-Uploads getestet — gemischtes Ergebnis, verworfen
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
|
||||
Getestet am 2026-07-18 (Tenant 3, Dokumente 3/4/5/6/7/8/12, `reprocess-all -tenant 3`) auf Architect-Empfehlung: den externen ImageMagick-`deskewImage()`-Schritt in `runTesseract()` (internal/ocr/ocr.go) komplett auslassen und stattdessen nur Tesseracts eigene interne textzeilenbasierte Skew-Korrektur (läuft mit `--psm 1`/OSD-Layoutanalyse automatisch mit) wirken lassen.
|
||||
|
||||
**Wichtiger struktureller Befund:** `runTesseract()` ist der einzige Aufrufpfad für `deskewImage()` und wird sowohl von `ocrImage()` (direkte Foto-Uploads) als auch von `pdfRasterOCR()` (pdftoppm-gerasterte PDF-Seiten) genutzt — es gibt KEINE getrennte Foto- vs. PDF-Pipeline. Eine "nur für Fotos deaktivieren"-Änderung würde also eine neue Unterscheidung am Aufrufort brauchen, die aktuell nicht existiert.
|
||||
|
||||
Ergebnis: gemischt, kein eindeutiger Gewinn.
|
||||
- Doc 5: 742 → 854 Zeichen (besser ohne Deskew)
|
||||
- Doc 12: 919 → 975 Zeichen (besser ohne Deskew)
|
||||
- Doc 3: 930 → 923 Zeichen (~gleich)
|
||||
- Doc 6, 8: identisch (Deskew griff hier kaum, erkannter Winkel nahe 0)
|
||||
- Doc 4: 779 → 737 Zeichen (schlechter ohne Deskew)
|
||||
- **Doc 7: 617 → 413 Zeichen (deutlich schlechter ohne Deskew)** — klarer Ausreißer nach unten, disqualifiziert die Änderung.
|
||||
|
||||
Code-Änderung in `runTesseract()` (deskewImage-Aufruf auskommentiert) wurde verworfen, Server zurück auf Original mit aktivem Deskew deployt (rsync+update.sh 2026-07-18, Backend+Frontend laufen bestätigt), `ocr_text` in DB per erneutem `reprocess-all -tenant 3` wieder auf den Mit-Deskew-Stand gebracht.
|
||||
|
||||
**Why:** Doc 7 als deutlicher Ausreißer nach unten zeigt, dass Tesseracts interne Skew-Korrektur den externen ImageMagick-Deskew nicht zuverlässig ersetzt — bei manchen Dokumenten (v.a. stärker verkippten) ist die externe Vorkorrektur weiterhin nötig, auch wenn sie bei anderen (Doc 5/12) leicht bremst. Kein klares Muster, welche Dokumente von welchem Ansatz profitieren.
|
||||
|
||||
**How to apply:** Bei künftigen Anfragen "Deskew für Fotos deaktivieren" NICHT erneut pauschal vorschlagen — Ergebnis ist dokumentiert negativ/gemischt. Falls die Idee wieder aufkommt, bräuchte es erst eine größere Testdokument-Stichprobe und eine begründete Heuristik (z.B. nur bei erkanntem angle_deg unter einem Schwellwert deaktivieren), nicht ein pauschales Weglassen. Siehe auch [[project_deskew_border_trick_tested_negative]] (verwandter, ebenfalls verworfener Deskew-Test) und [[project_title_heuristic_and_osd_zero_rotate_gap]].
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: project_deskew_preprocessing
|
||||
description: Deskew-Vorverarbeitungsschritt (ImageMagick) gegen Schräglage in der OCR-Pipeline, ergänzend zum OSD-90°-Rotationsfix
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
|
||||
Am 2026-07-16 wurde `deskewImage()` in `internal/ocr/ocr.go` ergänzt: `convert <src> -deskew 40% <dst>` läuft in `runTesseract()` VOR der bestehenden OSD-basierten 90°/180°-Rotationskorrektur (`rotateForOSD`). Grund: Tesseract-OSD erkennt nur 90°-Schritte, keine Feinneigung (wenige Grad Schräglage bei Scans/Handyfotos).
|
||||
|
||||
**Server-Paket-Falle:** `imagemagick-7-common` war auf 192.168.1.204 bereits installiert, lieferte aber KEINE `convert`/`magick`-Binary — nur Infrastruktur/Metapaket. Die echte Binary kommt erst mit dem Paket `imagemagick` (zieht `imagemagick-7.q16`, `netpbm`, `libnetpbm11t64` als Abhängigkeiten). Bei zukünftigen "convert nicht gefunden"-Diagnosen zuerst `dpkg -l | grep imagemagick` prüfen, nicht nur `which convert`.
|
||||
|
||||
**Threshold-Wahl:** 40% manuell gegen dms doc ids 2/7/8 verifiziert (deutliche Verbesserung, besonders doc 7). 80% probeweise getestet — überrotierte einen kontrastarmen Beleg (doc 8) und verschlechterte das Ergebnis. Bei neuen Problemfällen mit 40% starten, nur bei Bedarf pro Dokumenttyp anpassen, nicht pauschal erhöhen.
|
||||
|
||||
**Muster:** best-effort wie `rotateForOSD` — eigene `deskewImage()`-Methode mit `(dstPath string, cleanup func(), ok bool)`-Signatur, Fehler/Timeout/fehlende Binary führen zu `ok=false`, Original-Datei wird ohne Deskew weiterverwendet, kein Abbruch der OCR-Pipeline.
|
||||
|
||||
**Why:** Nutzer meldete nach dem OSD-Fix, dass das eigentliche verbleibende Problem Schräglage ist, nicht 90°-Rotation — OSD kann das strukturell nicht lösen.
|
||||
|
||||
**How to apply:** Bei weiteren OCR-Qualitätsproblemen mit schräg liegendem Text zuerst prüfen ob `deskewThreshold` (aktuell 40%, Konstante in ocr.go) für den konkreten Dokumenttyp passt, bevor neue Sidecars (unpaper etc.) vorgeschlagen werden — [[feedback_scope_code_and_deploy_only]] gilt auch hier, keine Übertechnisierung ohne nachgewiesenen Bedarf.
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: project_title_heuristic_and_osd_zero_rotate_gap
|
||||
description: titleFromOCRText Rauschfilter (Alnum-Ratio) + bekannte Lücke in rotateForOSD bei Rotate:0-Fehlerkennung
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
|
||||
Am 2026-07-16 wurde `titleFromOCRText` (`internal/api/document_handlers.go`) um einen Rauschfilter ergänzt: Kandidatenzeile muss ≥3 Zeichen UND Anteil Buchstaben/Ziffern an Nicht-Leerzeichen ≥75% haben (`isUsableTitleLine`), Scan auf erste 8 Zeilen begrenzt. Verworfene Alternative: "längste Zeile statt erste passende Zeile nehmen" — regressierte bei Tenant-3-Testdokumenten (3,4,5,7) den korrekten Titel "Eni Service-Station" zugunsten falscher langer Zeilen wie "Tankstellen-Nr.: ...". Per Python-Simulation der Go-Logik gegen echte `ocr_text`-Werte verifiziert, bevor Code geändert wurde (kein lokaler `go build` verfügbar in diesem Repo-Setup).
|
||||
|
||||
**Bekannte Lücke — nicht gefixt:** `rotateForOSD` (`internal/ocr/ocr.go` ~Zeile 500) bricht bei `degrees == 0` sofort ab, OHNE die OSD-Konfidenz zu prüfen. Bei Dokument 9 (Tenant 3) meldete OSD `Rotate: 0` mit nur 0,68 Konfidenz (deutlich niedriger als die 5-7 bei den korrekt erkannten Dokumenten) — tatsächlich hätte 90° geholfen (manuell mit `convert -rotate 90` verifiziert, lieferte vereinzelte lesbare Fragmente). Trotzdem NICHT als generischen Fix umgesetzt: das Grundproblem bei Dokument 9 ist massive Bildunschärfe, selbst mit korrekter Rotation blieb der Großteil des Texts unlesbar — ein "bei degrees==0 und niedriger Konfidenz trotzdem probeweise rotieren"-Fix hätte hier nichts gebracht und das Risiko gehabt, gute unrotierte Scans woanders zu verschlechtern. Bei zukünftigen ähnlichen Fällen (OSD meldet Rotate:0 mit auffällig niedriger Konfidenz UND Ergebnis ist unlesbar): zuerst mit `convert -rotate {90,180,270}` + `tesseract --psm 6` von Hand durchprobieren, ob es überhaupt an der Rotation liegt, bevor am Code gedreht wird — reine Bildqualität (Unschärfe) ist nicht softwareseitig reparierbar.
|
||||
|
||||
**Why:** Nutzer wollte robustere Titel-Ableitung ohne Overengineering, und klare Diagnose statt Pseudo-Fix bei technisch nicht behebbaren Dokumenten.
|
||||
|
||||
**How to apply:** [[project_deskew_preprocessing]] ergänzend — bei neuen schlecht lesbaren Dokumenten immer erst Bildqualität/Schärfe von Hand prüfen (`convert -resize 400x400 preview.png` + Beschreibung, da kein Bildschirm verfügbar), bevor an Rotations-/Deskew-Schwellwerten gedreht wird.
|
||||
@@ -0,0 +1 @@
|
||||
- [GoBD-Verfahrensdokumentation-Export](project_gobd_verfahrensdokumentation.md) — Gliederung geklärt, was automatisch/manuell ableitbar, Konzeptstand 2026-07-30, noch kein Code
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
name: project_gobd_verfahrensdokumentation
|
||||
description: GoBD-Verfahrensdokumentation-Export-Feature — Gliederung, was automatisch/manuell ableitbar, Konzeptstand
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
|
||||
Feature-Idee (aus Paperless-Kursvergleich, siehe [[project_paperless_pilot_kurs_vergleich]]): automatisch generierte
|
||||
GoBD-Verfahrensdokumentation aus archivdms-Systemdaten, potenzielles Alleinstellungsmerkmal ggü. Paperless-ngx/ecoDMS.
|
||||
Stand 2026-07-30: Konzept fertig geklärt, KEIN Code geschrieben.
|
||||
|
||||
**Gliederung (GoBD-Standard, BMF-Schreiben Rz.151-155 + Fachpraxis):**
|
||||
1. Allgemeine Beschreibung (Organisation, Verantwortliche) — MANUELL, nicht im System
|
||||
2. Anwenderdokumentation (Erfassungsprozesse) — teilweise automatisch (workflows/classification_templates)
|
||||
3. Technische Systemdokumentation (Hard-/Software) — MANUELL/Platzhalter
|
||||
4. Betriebsdokumentation (Backup, Notfall, Zugriffsschutz) — Zugriffsschutz automatisch (permission_groups+Grants),
|
||||
Backup/Notfall MANUELL
|
||||
5. Verfahrensabläufe: Erfassung/Indizierung/Verarbeitung/Speicherung/Absicherung/Fristen/Vernichtung/Wiederauffinden
|
||||
— größtenteils automatisch ableitbar
|
||||
6. Änderungshistorie der Doku selbst — MANUELL (oder: Zeitstempel "Stand: <Datum>" bei jeder Live-Generierung)
|
||||
|
||||
**Automatisch ableitbar aus echtem Code-Stand (geprüft, nicht geraten):**
|
||||
- Fristen-Kapitel: `retention_rules` Tabelle (Migration 022) — trigger_type, retention_years/days, legal_basis,
|
||||
dsgvo_conflict, Präzedenz doc-typ-spezifisch > tenant-Default
|
||||
- Zugriffsschutz-Kapitel: `permission_groups` + `document_type_grants`/`tag_grants`/`document_grants`
|
||||
(Migration 008), Rollenmodell superadmin/domain_admin/user
|
||||
- Löschkonzept-Kapitel: `document_delete_requests` (Migration 007) — Vier-/Zwei-Augen-Workflow, Status
|
||||
pending/confirmed/executed/blocked_retention, `documents.deleted_at/deleted_by`
|
||||
- Unveränderbarkeit: chmod 0440 + SHA-256 Content-Hash — technische Fließtext-Aussage, kein DB-Query nötig
|
||||
- Erfassungsprozess (teilweise): `workflows`/`workflow_actions`/`workflow_runs` (Migration 012),
|
||||
`classification_templates` (Migration 011)
|
||||
- Nachvollziehbarkeit: `audit_log` append-only via BEFORE UPDATE/DELETE Trigger (Migration 001)
|
||||
|
||||
**Zwingend manuell (nicht im System):** Organisationsbeschreibung, Verantwortliche/Vertretungsregeln,
|
||||
Server-/Backup-/Notfallkonzept außerhalb des DMS, Änderungshistorie der Doku selbst.
|
||||
|
||||
**Format-Entscheidung:** Markdown als Primärformat (kein PDF-Sidecar im ersten Schritt), pro Mandant individuell
|
||||
(alle relevanten Tabellen sind tenant-skopiert), live aus aktuellem DB-Stand generiert (kein Caching), mit
|
||||
Zeitstempel-Hinweis "Stand: <Datum>, kein rechtsverbindliches Fertigdokument".
|
||||
|
||||
**Endpoint-Vorschlag:** `GET /api/compliance/procedure-documentation`, Auth-Pattern wie
|
||||
`internal/api/retention_rule_handlers.go` (domain_admin+ für eigenen Tenant, superadmin optional mit
|
||||
`?tenant_id=` für Cross-Tenant, aber kein automatisches Vermischen mehrerer Mandanten in einem Dokument).
|
||||
|
||||
**Warum kein Code in diesem Durchgang:** Der generierte Text kann vom Kunden gegenüber dem Finanzamt/Betriebsprüfer
|
||||
verwendet werden — Formulierungsrisiko, nicht Technikrisiko. Empfehlung: Konzept an backend-dev übergeben mit
|
||||
dieser Tabelle als Vorgabe, Platzhalter-Abschnitte klar als "TODO: durch Mandant auszufüllen" markieren,
|
||||
Rechtsgrundlagen-Texte vor Go-Live durch retention-compliance-Rolle gegenlesen lassen.
|
||||
|
||||
**How to apply:** Bei Fortsetzung dieses Features zuerst hier nachlesen statt Gliederung neu zu recherchieren.
|
||||
Code-Stand der referenzierten Tabellen vor Umsetzung erneut gegen aktuelle Migrations-Dateien prüfen (Stand könnte
|
||||
sich geändert haben).
|
||||
Reference in New Issue
Block a user