RUDI RegioFrucht Unternehmens Daten Intelligenz
RUDI ist die KI-gestuetzte Unternehmens-Intelligenz der Regio Frucht GmbH (kuechenfertige Verarbeitung von Obst, Gemuese und Salaten). RUDI kombiniert einen Claude-basierten KI-Chat mit einem vollstaendigen QMS-System nach IFS Food 8.
Kernfunktionen
- KI-Chat mit Tool-Zugriff auf Dateisystem, QMS und System
- QMS Dashboard mit Gap-Analyse (127 IFS-Anforderungen, Ampelsystem)
- Automatische Dokumentenerstellung aus Firmenvorlage (Word DOCX)
- Dateibrowser mit Vorschau fuer PDF, Excel, Word, Code
- Spracheingabe (Web Speech API + Whisper-Transkription)
Modul-Uebersicht
Alle RUDI-Module auf einen Blick. Fuer die interaktive Version: System-Karte
| Modul | Frontend | API-Route | ~Endpunkte | Claude-Tools | Status |
|---|---|---|---|---|---|
| Chat | /chat/ | chat.js | 1 (SSE) | 68 (alle) | aktiv |
| QMS | /qms/ | qms.js | ~20 | gap_analysis, search_qms_files, create_qms_document, ... | aktiv |
| Reklamationen | /qms/reklamation.html | qms.js | 7 | qms_save_erkenntnis, qms_create_document | aktiv |
| Maschinen | /maschinen/ | maschinen.js | 18 | maschinen_liste, maschinen_info, wartung_* | aktiv |
| Vorschlaege | /vorschlaege/ | vorschlaege.js | 8 | vorschlag_erstellen, vorschlaege_lesen, ... | aktiv |
| Pipeline | /pipeline/ | pipeline.js | 16 | pipeline_save_hinweis, pipeline_read_hinweise | aktiv |
| Einkauf | /einkauf/ | einkauf.js | ~12 | (via Chat-Kontext) | aktiv |
| Fuhrpark | (Dashboard-Kachel) | fuhrpark.js | ~10 | (via Chat-Kontext) | aktiv |
| Produktionsplanung | /produktionsplanung/ | produktionsplanung.js | ~8 | get_batch_plan | aktiv |
| Intelligence | (via Chat) | intelligence.js | 6 | semantic_search, find_similar | aktiv |
| Kommunikation | /kommunikation/ | email.js, kalender.js | ~18 | email_inbox, email_senden, kalender_termine, kalender_termin_erstellen | aktiv |
| QMS-E-Mail | (im QMS-Dashboard) | qms.js (Email-Endpoints) | ~8 | qms_email_inbox, qms_email_entwurf | aktiv |
| System | /system/ | system.js | 5 | system_info, audit_run | aktiv |
| Dateien | /dateien/ | files.js | ~15 | read_file, write_file, list_directory, ... | aktiv |
| HFX360 | /hfx360/ | hfx360.js | ~25 | hfx360_api_status, hfx360_auftrag_vorschau | aktiv |
| Verkauf | /verkauf/ | kunden.js | ~10 | kunden_info, kunden_liste, kunden_touren_uebersicht | aktiv |
| Etiketten | /etiketten/ | etiketten.js | ~12 | (via Agent-Token) | aktiv |
| Mein RUDI PWA | /mein/ | mein.js | ~30 | memory_*, mein_config, todo_*, routine_*, mail_regel_verwalten | aktiv |
| Admin | /admin/ | auth.js (admin) | ~8 | — | aktiv (nur Rolle admin) |
| Benachrichtigungen | /benachrichtigungen/ | push.js | ~6 | — | aktiv (VAPID) |
| Downloads | /downloads/ | (statisch) | — | — | Notfall-PDF |
| Lager | /lager/ | lager.js | ~14 | lager_artikel_*, lager_platz_*, lager_bild_analysieren, lager_stats | aktiv |
| Leergut | /leergut/ | leergut.js | ~6 | (geplant 2026-Q3, OCR+Vision+Acumatica) | Frontend-Stub |
| Intratool | /intratool/ | intratool.js | ~5 | — | aktiv (Token-Auth) |
| Verkaufsanalyse | /verkaufsanalyse/ | verkaufsanalyse.js | ~6 | verkaufsmengen_abfragen | aktiv |
| Verkaufspreise | /verkaufspreise/ | (statisch + via Einkauf) | — | preise_abfragen, preis_analyse | aktiv |
| Bestellungen | /einkauf/bestellungen.html | bestellung.js | ~7 | bestellung_erfassen, bestellung_kopieren | aktiv |
Architektur
Internet
|
HTTPS (Let's Encrypt)
|
Nginx Reverse Proxy (:443)
|-- Basic Auth (global)
|-- Security Headers (HSTS, CSP, XSS)
|-- Rate Limiting (10 req/min Chat)
|
|-- / --> /var/www/html/ (Zentrale)
|-- /qms/ --> /var/www/qms/ (QMS Dashboard)
|-- /system/ --> /var/www/html/system/ (System Dashboard)
|-- /dateien/ --> /var/www/dateien/ (Dateibrowser)
|-- /chat/ --> proxy 127.0.0.1:3456 (Node.js App)
|-- /chat/api/* --> proxy 127.0.0.1:3456 (REST API)
Node.js/Express (:3456, nur localhost)
|-- Claude API (claude-opus-4-6)
|-- Agentic Tool Loop (max 10 Iterationen)
|-- 14 Tools
|-- SSE Streaming
Projektstruktur
| Pfad | Inhalt |
|---|---|
~/rudi-chat/server.js | Backend Entry-Point (Express-Setup, Route-Mounting, 39 Zeilen) |
~/rudi-chat/lib/shared.js | Gemeinsame Funktionen, Pfade, Konstanten, QMS-Helpers |
~/rudi-chat/lib/tools.js | TOOLS-Array, System-Prompt, executeTool (Claude-Tools) |
~/rudi-chat/lib/validation.js | Zentraler Validation-Helper (Phase 0) — Mengen, Preise, Belegnummern, Datum, IBAN, USt-ID, E-Mail, Country-ISO, Chargennummern, Lieferanten-Alias, validateAll-Batch |
~/rudi-chat/lib/validation.test.js | Standalone-Testskript (100 Tests, kein Test-Runner) — node ~/rudi-chat/lib/validation.test.js |
~/rudi-chat/routes/chat.js | Chat-API mit SSE-Streaming und Agentic Loop |
~/rudi-chat/routes/qms.js | QMS-Dashboard, Annotations, Recurring, Upload APIs |
~/rudi-chat/routes/system.js | System-Status API (CPU, RAM, Disk, Services) |
~/rudi-chat/routes/vorschlaege.js | Änderungsvorschläge CRUD + Datei-Upload API |
~/rudi-chat/routes/files.js | Datei-Viewer, Chats CRUD, Upload, Transkription |
~/rudi-chat/public/ | Chat-Frontend (erreichbar unter /chat/) |
~/rudi-chat/chat-history/ | Chat-Verlaeufe (JSON pro Chat/User) |
~/rudi-chat/audio-handler.js | Whisper-Transkription |
/var/www/html/ | Zentrale (Startseite) |
/var/www/qms/ | QMS Dashboard + Aufgaben |
/var/www/dateien/ | Dateibrowser |
~/qms/QMS/ | QMS-Dateien (unsortiert + Struktur) |
~/qms/QMS/QMS_RegioFrucht/ | Neue QMS-Ordnerstruktur (IFS-konform) |
~/qms/QMS/output/arbeitsdaten/ | IFS-Mapping (JSON, Excel) |
~/qms/QMS/Vorlagen/ | DOCX-Vorlage + Skill-Referenz |
/var/www/html/system/ | System Dashboard |
/var/www/html/shared/ | Shared Components (Chat-Panel CSS + JS) |
~/uploads/ | Benutzer-Uploads (max 50 MB) |
~/bin/ | Hilfsskripte (Layout-Test, Tree-Generator) |
Schnellstart
Zugang
URL: https://rudi-regiofrucht.de
Auth: Basic Authentication (Benutzername/Passwort)
Was kann ich RUDI fragen?
- QMS: "Zeige die Gap-Analyse fuer Kapitel 4" / "Erstelle ein Dokument fuer 4.10.1" / "Batch-Plan fuer alle gruenen Anforderungen"
- Dateien: "Lies die Datei qms/QMS/unsortiert/..." / "Was steht in der Excel?"
- System: "Wie ist der Speicherstand?" / "Welche Dienste laufen?"
- Aufgaben: "Erstelle eine monatliche Pruefung fuer Temperaturkontrolle"
Zentrale
Die Startseite unter / zeigt 4 Kacheln im Apple-Glasmorphism-Design:
- Chat – KI-Chat mit vollem Tool-Zugriff
- System & Dateien – Server-Status (Live-Badge) + Dateibrowser-Zugang
- QMS – IFS Gap-Analyse Dashboard (mit integriertem Aufgaben-Tab, Live-Badge)
- Dokumentation – Diese Seite
Das System-Badge laedt dynamisch den Server-Status und zeigt "Alles OK" oder Warnungen an.
Chat
Der Chat unter /chat/ ist das Herztueck von RUDI. Features:
- Echtes Streaming: Text erscheint Zeichen fuer Zeichen (via
client.messages.stream()) - Live Tool-Status: Zeigt in Echtzeit welche Tools RUDI gerade nutzt (Dateien lesen, Dokumente erstellen etc.)
- Sidebar: Chat-Liste mit Suche, Gruppierung (Chats/QMS/Recurring/Admin), Filter-Pills (Alle/Chats/QMS/Aufgaben), Erstellen/Umbenennen/Loeschen
- Papierkorb: Geloeschte Chats werden in Papierkorb verschoben mit Wiederherstellen-Option
- Markdown-Rendering: Tabellen, Code-Bloecke mit Syntax-Highlighting und Kopier-Button
- Datei-Upload: Drag & Drop oder Dateiauswahl, Dateien werden im Chat referenziert
- Spracheingabe: Web Speech API (live) oder Whisper-Transkription (Audio-Aufnahme)
- Dark/Light Mode: System-Praeferenz + manueller Toggle
- Auto-Titel: Chats werden nach der ersten Antwort automatisch benannt
Kontext-Links
Der Chat kann mit Kontext gestartet werden:
| URL-Parameter | Effekt |
|---|---|
?start=system | Startet automatisch einen Systembericht |
?start=recurring&rec_id=... | Oeffnet eine wiederkehrende Aufgabe |
?context=IFS_4.10.1 | Stellt IFS-Kontext bereit (Anforderung + Leitfaden + Dokumente) |
?open=chatId | Oeffnet einen bestehenden Chat |
Dokumenten-Pipeline
Die Dokumenten-Pipeline unter /pipeline/ verarbeitet eingehende Papierdokumente automatisch. Dokumente werden per Scanner (FTP/FTPS) oder manuellen Upload eingespeist.
Pipeline-Ablauf (Phase 5: Dual-Processing + Vorgang-Verlinkung)
- Eingang: Scanner sendet PDF per FTPS an
eingang/odereingang_personal/ - OCR (Dual-Processing): pdfplumber/Tesseract PLUS Claude Vision Cross-Check (Flag
pipeline_vision_crossON)- Similarity-Ratio > 0.80: Vision-Text bevorzugt (besser bei Tabellen/Layout), conf=0.95
- Similarity-Ratio ≤ 0.80: Beide Texte kombiniert, conf=0.70
- Vision fehlgeschlagen: Tesseract-Fallback automatisch
- Tagesbudget: max 50 Vision-Calls/Tag (
PIPELINE_VISION_MAX). Audit-Log: modul=pipeline-vision
- Lieferanten-Normalisierung: Alias-Resolver gegen
lieferant_aliase-Tabelle - Dedup-Check: SHA-1-Hash ueber Lieferant+Belegnummer+Betrag+Datum; Duplikate nach
~/pipeline/duplikate/ - Klassifikation: Claude API (Sonnet) extrahiert Metadaten als JSON
- Ablage: Datei umbenannt + verschoben
- DB-Eintrag: pipeline.db mit allen Daten inkl.
dedup_hash - Vorgang-Verlinkung (NEU): Pipeline-Dokument wird mit Vorgang in einkauf.db verlinkt (
vorgang_referenz.beleg_db='pipeline'). Fuzzy-Lieferant-Match, offener Vorgang ±30 Tage. Kein Vorgang: auto-angelegt. - Abgleich: Automatischer Abgleich Lieferschein/Rechnung
Lieferanten-Aliase
Tabelle lieferant_aliase in pipeline.db normalisiert Schreibvarianten auf kanonische Namen.
Migrations-Skript: ~/pipeline/migrations/001_lieferant_aliase.py (idempotent).
Aktuell 10 Aliase konfiguriert (Stand 2026-04-27).
Dedup-Hash & Duplikatserkennung
Spalte dedup_hash (SHA-1 ueber Lieferant|Belegnummer|Betrag|Datum) verhindert Doppeleintraege bei Re-Upload.
Bestehende Duplikate werden in ~/pipeline/duplikate_vorschlag.json dokumentiert (kein automatisches Loeschen).
Migrations-Skript: ~/pipeline/migrations/002_dedup_hash.py (idempotent, Backfill aller vorhandenen Dokumente).
Dashboard-Funktionen
- Statistik-Karten: Heute verarbeitet, Gesamt, Fehler, Offene Abgleiche
- Dokumente-Tab: Dokumentenliste mit Filtern (Kategorie, Status, Suchfeld), klickbare Detail-Ansicht
- LS/RE-Abgleich-Tab: Uebersicht der automatischen Lieferschein/Rechnungs-Zuordnungen
- Alerts-Tab: Fehler-Meldungen und offene Rechnungen ohne Abgleich
- Upload: Zwei Upload-Buttons – allgemein (nach
eingang/) und Personal (nacheingang_personal/, vertraulich) - Status-Aenderung: Im Detail-Modal kann der Status manuell geaendert werden
Dokument-Kategorien
| Kategorie | Beschreibung | Zielordner |
|---|---|---|
lieferant_ls | Lieferschein (Lieferant) | lieferanten/lieferscheine/{Name}/ |
lieferant_re | Rechnung (Lieferant) | lieferanten/rechnungen/{Name}/ |
kunde_ls | Lieferschein (Kunde) | kunden/lieferscheine/{Name}/ |
gutschrift | Gutschrift | kunden/gutschriften/ |
personal_* | Personaldokumente (7 Unterkategorien) | personal/{Nachname_Vorname}/{Typ}/ |
schriftverkehr_* | Behoerden, Versicherungen, Sonstiges | schriftverkehr/{Typ}/ |
Scanner-Anbindung (FTPS)
- Scanner: Sharp BP-56C26 per FTP/FTPS (vsftpd)
- Profil "RUDI - Allgemein": User
scanner→eingang/ - Profil "RUDI - Personal": User
scanner-personal→eingang_personal/(sofort vertraulich) - SSL: Let's Encrypt Zertifikat, Passive Mode Ports 40000-40100
Hintergrundprozess
- Service: Kein eigenstaendiger systemd-Service. Start manuell:
cd ~/pipeline && source venv/bin/activate && python pipeline.py - Logs:
sudo journalctl -u regio-pipeline -f - Pfad:
~/pipeline/(pipeline.py, classifier.py, ocr.py, db.py, config.py, vorgang_link.py [NEU Phase 5]) - Migrations:
~/pipeline/migrations/(001_lieferant_aliase.py, 002_dedup_hash.py) - DB:
~/pipeline/pipeline.db(SQLite, WAL-Modus, Tabellen: dokumente, abgleich_log, pipeline_log, mitarbeiter, artikel_positionen, lieferant_aliase) - Duplikat-Report:
~/pipeline/duplikate_vorschlag.json - Duplikate-Ablage:
~/pipeline/duplikate/(Re-Uploads mit gleichem Hash) - DSGVO: Personaldokumente werden als vertraulich markiert, OCR-Text wird nicht gespeichert
QMS Dashboard
Das QMS Dashboard unter /qms/ ist als Tab-System aufgebaut mit zwei Tabs:
Tab: Dashboard (Gap-Analyse)
- Gesamt-Header: Stats-Karten (Total/Abgedeckt/Teilweise/Fehlend/Offene Aufgaben), Fortschrittsbalken mit 3 Farbsegmenten
- 5 Kapitel-Karten: Aufklappbar mit Ampel-Badges (Gruen/Gelb/Rot), Abdeckungsprozent, Mini-Fortschrittsbalken
- Anforderungsliste: Sortiert (Rot zuerst), mit Status-Icon, IFS-Ref, Task-Badge, Dokumentenanzahl
- Detail-Panel: Tasks (Checkbox + Doppelklick-Edit + Loeschen), Notizen (Auto-Save), Dokumente
- Quick-Chat: Slide-in-Panel mit IFS-Kontext, Quick-Action-Chips, SSE-Streaming
- Upload: Ordner-Upload (webkitdirectory), Drag & Drop, Zielordner-Auswahl, Fortschrittsbalken
- Eigene Punkte: Custom-Tasks mit Label und Checkbox
Tab: Aufgaben
Integrierter Aufgaben-Tab (erreichbar ueber /qms/#aufgaben) mit:
- IFS-Aufgaben: Pro-Anforderung Tasks mit Checkbox, Bearbeiten, Loeschen
- Wiederkehrende Aufgaben: Recurring Tasks mit Ampelstatus, Erledigen-Button, Historie
- Stats-Leiste: Gesamt/Offen/Erledigt/Ueberfaellig Zaehler
- Filter: Alle/Offen/Erledigt/Ueberfaellig mit Such-Funktion
- Lazy Loading: Daten werden erst beim ersten Tab-Wechsel geladen
- Tab-Badge: Zeigt Anzahl offener Aufgaben im Tab-Button
Ampelsystem
| Farbe | Bedeutung | Kriterium |
|---|---|---|
| Gruen | Abgedeckt | 2+ Quelldokumente zugeordnet |
| Gelb | Teilweise | 1 Quelldokument zugeordnet |
| Rot | Fehlend | Keine Dokumente zugeordnet |
Dateibrowser
Der Dateibrowser unter /dateien/ zeigt die gesamte RUDI-Verzeichnisstruktur:
- Baumansicht: Laedt
tree.json(generiert vongenerate-tree.sh) - Echtzeitsuche: Filter ueber Dateinamen
- Dateivorschau: PDF (iframe), Bilder, Excel (Handsontable), Word (mammoth.js), Markdown, Code (Syntax-Highlighting)
- Download-Button fuer jede Datei
- Upload: Gleiche Upload-Funktion wie QMS Dashboard
System Dashboard
Das System Dashboard unter /system/ zeigt Server-Informationen in Echtzeit:
- Status-Karten: Uptime, CPU Load, RAM-Nutzung, Disk-Nutzung, Dienste-Status
- Dienste-Uebersicht: rudi-chat, nginx, fail2ban, ufw mit Live-Status (aktiv/inaktiv)
- Detailsektionen: CPU-Modell, RAM-Details, Disk-Details, System-Info (aufklappbar)
- Fortschrittsbalken: Farbcodiert (gruen/gelb/rot) je nach Auslastung
- Auto-Refresh: Daten werden alle 60 Sekunden automatisch aktualisiert
- Integrierter Chat: RUDI fragen-Button oeffnet System-Chat mit Kontext-Chips
Die Daten kommen von der API-Route /chat/api/system/status, die CPU, RAM, Disk und Services ueber das os-Modul und systemctl abruft.
System-Karte (/system/map.html)
Die System-Karte bietet eine interaktive, statische Uebersicht aller RUDI-Komponenten als aufklappbarer Baum:
- Interaktiver Baum: 108 Komponenten in 7 Hauptkategorien (Backend, Frontend, KI & Wissen, Claude Code, Infrastruktur, Externe Dienste)
- Echtzeit-Suche: Filterung des Baums nach Name oder Beschreibung
- Detail-Panel: Klick auf einen Knoten zeigt Beschreibung, Dateipfad, Badge und Unterkomponenten
- Status-Dots: Farbkodierung gruen=aktiv, orange=in_arbeit, grau=pausiert, rot=problem
- Kein API-Aufruf: Vollstaendig statisch — keine Backend-Abhaengigkeit
- Responsive: Mobile zeigt Baum oben, Detail-Panel darunter
Änderungsvorschläge
Die Seite /vorschlaege/ sammelt Ideen, Verbesserungen und Bugfixes für RUDI. Vorschläge können manuell per Formular oder im Gespräch mit RUDI erstellt werden.
Funktionen
- Manuell erstellen: Button "Neuer Vorschlag" leitet zu
/vorschlaege/detail.html(eigenständige Seite, kein Modal) - Detailseite (
/vorschlaege/detail.html): Vollständiges Formular mit Titel, Beschreibung, Kategorie, Priorität, Status (nur Edit), Drag&Drop-Datei-Upload, Bild-Galerie mit Lightbox, Datei-Löschen - Per RUDI-Chat: "RUDI fragen"-Button öffnet das Chat-Panel – RUDI legt Vorschläge automatisch über Tools an (
vorschlag_erstellen,vorschlaege_lesen,vorschlag_aktualisieren) - Lightbox: Bild-Vollansicht mit Vor/Zurück-Navigation, Tastatur-Steuerung (ESC, Pfeiltasten), Download-Link
- Medien-Upload im Chat: Dateien können auch direkt im RUDI-Chat angehängt werden (Büroklammer-Button oder Drag & Drop)
- Bearbeiten: Vorschläge aktualisieren, Status ändern (Offen, In Arbeit, Erledigt, Abgelehnt)
- Löschen: Vorschläge mit Bestätigungsdialog entfernen (inkl. aller hochgeladenen Dateien)
- Filter: Nach Status, Kategorie und Priorität filtern
- Datei-Vorschau: Bild-Galerie in der Detailseite, Thumbnails in den Listenkarten
RUDI-Tools (Vorschläge-Kontext)
Wenn das Chat-Panel auf der Vorschläge-Seite geöffnet wird, erhält RUDI drei zusätzliche Tools:
| Tool | Beschreibung |
|---|---|
vorschlag_erstellen | Legt einen neuen Vorschlag an (Titel, Beschreibung, Kategorie, Priorität) |
vorschlaege_lesen | Liest alle Vorschläge, optional nach Status gefiltert |
vorschlag_aktualisieren | Ändert Titel, Beschreibung, Kategorie, Priorität oder Status eines Vorschlags |
API-Endpunkte
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | /chat/api/vorschlaege/ | Alle Vorschläge (neueste zuerst) |
| GET | /chat/api/vorschlaege/stats | Zähler für Dashboard-Badge |
| POST | /chat/api/vorschlaege/ | Neuen Vorschlag anlegen |
| POST | /chat/api/vorschlaege/:id/upload | Dateien an Vorschlag anhängen (max 10, 50 MB) |
| PATCH | /chat/api/vorschlaege/:id | Vorschlag bearbeiten |
| DELETE | /chat/api/vorschlaege/:id | Vorschlag + Dateien löschen |
| GET | /chat/api/vorschlaege/:id/dateien/:name | Datei ausliefern (Vorschau) |
| DELETE | /chat/api/vorschlaege/:id/dateien/:name | Einzelne Datei löschen |
Speicherung
- Daten:
~/rudi-chat/vorschlaege.json(JSON-Array, atomic writes) - Dateien:
~/uploads/vorschlaege/{id}/(pro Vorschlag ein Ordner) - Claude Code: Liest
vorschlaege.jsondirekt vom Dateisystem, um Vorschläge zu besprechen und umzusetzen
Agentic Loop
RUDI nutzt einen agentic Tool-Loop mit Claude. Das bedeutet: Claude kann eigenstaendig Tools aufrufen, die Ergebnisse lesen, und weitere Tools aufrufen – bis zu 10 Iterationen pro Nachricht.
Ablauf
- Benutzer sendet Nachricht
- Server sendet Nachricht + System-Prompt + letzte 20 Nachrichten an Claude API
- Claude antwortet mit Text und/oder Tool-Aufrufen
- Falls Tool-Aufrufe: Server fuehrt Tools aus, sendet Ergebnisse zurueck an Claude
- Schritte 3-4 wiederholen sich bis Claude fertig ist (max 10x)
- Finale Antwort wird per SSE gestreamt
- Automatische IFS-Verknuepfung im Hintergrund
Modell: claude-opus-4-6 | Max Tokens: 4096 | Streaming: Echtes SSE-Streaming (Zeichen fuer Zeichen)
Live Tool-Status
Waehrend RUDI im Hintergrund arbeitet (Dateien liest, Dokumente erstellt), zeigt das Chat-Frontend live an, welches Tool gerade laeuft:
- Blau pulsierend = Tool arbeitet (z.B. "Datei lesen – VA01_Hygienisch_Arbeiten.docx")
- Gruener Haken = Tool abgeschlossen
- Die Anzeige blendet sich nach Abschluss automatisch aus
Papierkorb
Geloeschte Chats werden nicht sofort entfernt, sondern in einen Papierkorb verschoben (soft delete):
- Papierkorb-Bereich unten in der Chat-Sidebar mit Zaehler
- Wiederherstellen oder endgueltig Loeschen pro Chat
- "Alle endgueltig loeschen" leert den gesamten Papierkorb
- Beim Loeschen werden automatisch alle IFS-Verknuepfungen (linkedChats in Annotations) bereinigt
RUDI Tools
RUDI hat 17 Tools zur Verfuegung. Jedes Tool wird von Claude eigenstaendig aufgerufen.
Datei & System
| Tool | Parameter | Beschreibung |
|---|---|---|
| read_file | path |
Liest Dateien: Text (max 500 KB), DOCX (max 10 MB, via PizZip), PDF (max 20 MB, via pdf-parse), Excel (max 10 MB, via xlsx). Pfad relativ zu /home/regiofrucht/. |
| list_directory | path |
Listet Dateien und Ordner auf. Zeigt Dateien mit Groesse (KB), Ordner mit Eintragsanzahl. |
| system_info | type |
Systeminformationen: disk, memory, cpu, services, network, uptime, overview |
QMS Analyse
| Tool | Parameter | Beschreibung |
|---|---|---|
| qms_gap_analysis | kapitel (opt.) |
IFS Gap-Analyse mit Ampelstatus. Zeigt pro Anforderung: Status, Dokumentenanzahl, Text. |
| qms_list_requirements | ref |
IFS-Anforderungen mit Leitfaden, zugeordneten Dokumenten und Status. |
| qms_source_documents | ref, read_content (opt.) |
Zeigt alle Quelldokumente einer IFS-Ref. Bei read_content=true: Liest vollen Text aus DOCX, PDF und Excel. |
| qms_batch_plan | kapitel (opt.), status (opt.) |
Erstellt Plan fuer Batch-Dokumentenerstellung. Zeigt welche Dokumente fehlen, schlaegt Typ vor. |
QMS Aktionen
| Tool | Parameter | Beschreibung |
|---|---|---|
| qms_create_folder | path |
Erstellt Ordner in QMS_RegioFrucht/. |
| qms_move_file | source, destination |
Kopiert Datei innerhalb QMS (Original bleibt erhalten). |
| qms_create_document | typ, kapitel, nummer, titel, version, zielordner, inhalt |
Erstellt DOCX aus Firmenvorlage. Ersetzt Header/Footer-Platzhalter, fuegt Inhalt ein (Markdown mit Tabellen). Dokumenttypen: VA, AA, FB, PB, CL, QMH. |
| qms_link_chat | refs (Array), summary |
Verknuepft Chat mit IFS-Anforderungen (wird auch automatisch im Hintergrund aufgerufen). |
Wiederkehrende Aufgaben
| Tool | Parameter | Beschreibung |
|---|---|---|
| qms_recurring_create | title, interval, responsible, ifs_ref, description, force |
Erstellt wiederkehrende Aufgabe mit Duplikat-Erkennung. Prueft automatisch ob eine aehnliche Aufgabe existiert (gleiche IFS-Ref oder aehnlicher Titel). Bei Treffer: Warnung statt Erstellung. Mit force=true trotzdem erstellen. |
| qms_recurring_complete | id, by, notes |
Markiert Aufgabe als erledigt, berechnet naechsten Faelligkeitstermin. |
| qms_recurring_list | – | Zeigt alle Aufgaben sortiert (ueberfaellig zuerst). |
Pipeline
| Tool | Parameter | Beschreibung |
|---|---|---|
| pipeline_status | – | Zeigt Pipeline-Statistiken: heute verarbeitet, Gesamtzahl, Fehler, offene Dokumente, offene Abgleiche. |
| pipeline_search | lieferant, kunde, kategorie, status, von, bis, limit |
Sucht Dokumente in der Pipeline-Datenbank nach verschiedenen Kriterien. |
| pipeline_match_invoice | – | Zeigt offene Rechnungen ohne Lieferschein-Zuordnung und bisherige Abgleich-Ergebnisse. |
Gap-Analyse
Die Gap-Analyse vergleicht 127 IFS Food 8 Grundstufe-Anforderungen (davon 11 KO-Anforderungen) mit den vorhandenen Dokumenten.
Datenquellen
| Datei | Inhalt |
|---|---|
all_grundstufe.json (101 KB) | 127 Anforderungen mit ref, Anforderungstext, Leitfaden, Stufe, KO-Status |
all_requirements.json (176 KB) | Alle 266 IFS-Anforderungen (Grund + Mittelstufe) |
refined_mapping.json (343 KB) | 621 Dokumente mit IFS-Zuordnung, Kategorie, Pfad, Vorschau |
Berechnung
Fuer jede Grundstufe-Anforderung wird gezaehlt, wie viele Dokumente aus dem Mapping zugeordnet sind. >=2 = Gruen, 1 = Gelb, 0 = Rot.
Dokumente erstellen
RUDI erstellt QMS-Dokumente in einem mehrstufigen Dialog:
- Vorhandene pruefen: Schon Dokumente fuer diese Anforderung vorhanden?
- Infos klaeren: Fehlende Informationen beim Benutzer abfragen (keine Platzhalter!)
- Entwurf zeigen: Vollstaendiger Entwurf im Chat
- Bestaetigung abwarten: Benutzer gibt OK
- Dokument erstellen: DOCX aus Vorlage generieren
Dokumenten-Kodierung
[Typ]-[Kapitel].[Nummer]_[Titel]_v[Version].docx
Beispiel: VA-4.10.001_Reinigungsplan_v1.0.docx
| Typ | Bedeutung |
|---|---|
| VA | Verfahrensanweisung |
| AA | Arbeitsanweisung |
| FB | Formblatt |
| PB | Pruefbericht |
| CL | Checkliste |
| QMH | QM-Handbuch |
Vorlage
Alle Dokumente basieren auf QMS-Vorlage-Regio-Frucht.docx:
- Header: Firmenlogo, Adresse, Handelsregister + Leiste mit Dok-ID, Version, Dokumentenname
- Footer: Erstellt von / Geprueft von / Freigabe von (mit Unterschriften-Bildern), Datumsfelder, Referenzzeile
- Body: Wird mit Markdown-Inhalt befuellt (Ueberschriften, Text, Listen, Tabellen)
Word-Tabellen
Markdown-Tabellen im Inhalt werden als formatierte Word-Tabellen gerendert:
- Header-Zeile: Akzentfarbe (#04B3D6) mit weisser Schrift
- Datenzeilen: Zebra-Streifen (#F0F8FF)
- Mehrzeilige Zellen:
\nfuer Zeilenumbruch
Batch-Erstellung
RUDI kann fuer alle gruenen/gelben Anforderungen automatisch Dokumente erstellen:
- Batch-Plan anfordern: "Erstelle alle gruenen Dokumente" oder "Batch-Plan fuer Kapitel 4"
- Plan bestauetigen: RUDI zeigt welche Dokumente erstellt werden
- Automatische Abarbeitung: Pro Anforderung: Quelldokumente lesen → echte Daten extrahieren → Dokument erstellen
- Fortschritt: "3/50 erstellt..."
Wichtig: RUDI verwendet nur echte Daten aus den Quelldokumenten – keine erfundenen Inhalte.
Wiederkehrende Aufgaben
Pruefungen, Checklisten und Formular-Durchgaenge koennen als wiederkehrende Aufgaben angelegt werden:
- Duplikat-Erkennung: Vor der Erstellung prueft RUDI automatisch ob eine aehnliche Aufgabe existiert (gleiche IFS-Ref oder aehnlicher Titel). Bei Treffer wird eine Warnung angezeigt – mit
force=truekann trotzdem erstellt werden. - Formblatt-Pruefung: Bei der Erstellung von Formblaettern prueft RUDI ob bereits eine passende wiederkehrende Aufgabe existiert und weist darauf hin.
- Intervalle: Taeglich, Woechentlich, Monatlich, Vierteljaehrlich, Halbjaehrlich, Jaehrlich
- Ampelstatus: Ueberfaellig (Rot), Bald faellig (<14 Tage, Gelb), OK (Gruen)
- Erledigung: Ueber Chat, QMS-Dashboard oder API
- Historie: Jede Erledigung wird mit Datum, Person und Notizen protokolliert
Kundenreklamationen
Das Reklamationsmodul ermoeglicht die strukturierte Erfassung, Bearbeitung und Dokumentation von Kundenreklamationen gemaess IFS 5.7.2–5.7.4.
Reklamation anlegen
Erreichbar ueber QMS Dashboard → Reklamationen → Neue Reklamation oder direkt unter /qms/reklamation.html.
- E-Mail-Import: .eml und .msg-Dateien (Outlook) per Drag & Drop oder Klick hochladen. RUDI analysiert automatisch Absender, Betreff und Inhalt und fuellt die Formularfelder vor.
- E-Mail-Text: Alternativ kann der E-Mail-Text direkt eingefuegt werden.
- Bild-Upload: .jpg, .png, .webp Bilder werden per Claude Vision analysiert (z.B. Fotos von beschaedigter Ware). Max. 15 MB pro Bild.
- PDF/Text-Upload: .pdf und .txt Dateien werden als Text extrahiert und mitanalysiert.
- Dateigroesse: Max. 50 MB pro E-Mail-Datei. Bei groesseren E-Mails mit Bildern kann die Analyse 1–2 Minuten dauern.
Formularfelder
| Feld | Pflicht | Beschreibung |
|---|---|---|
| Kunde | Ja | Name des reklamierenden Kunden |
| Datum | Ja | Reklamationsdatum (Standard: heute) |
| Produkt | Nein | Betroffenes Produkt / Artikel |
| Charge / Los-Nr. | Nein | Chargen- oder Losnummer zur Rueckverfolgung |
| Reklamationsgrund | Ja | Kategorie: Qualitaetsmangel, Fremdkoerper, Mindesthaltbarkeit, Falschlieferung, Transportschaden, Sonstiges |
| Beschreibung | Nein | Detaillierte Problembeschreibung |
| Sofortmassnahme | Nein | Bereits eingeleitete Sofortmassnahmen |
| Status | Ja | Offen, In Bearbeitung, Abgeschlossen |
| Dateien | Nein | Fotos, Lieferscheine, Pruefberichte etc. |
Entwurf & Speicherung
- Auto-Entwurf: Bei neuen Reklamationen werden Formulardaten automatisch im Browser (localStorage) gespeichert. Beim erneuten Oeffnen wird angeboten, den Entwurf wiederherzustellen.
- Status-Anzeige: Rechts oben zeigt ein Indikator den aktuellen Speicher-Status (Entwurf / Gespeichert / Ungespeicherte Aenderungen).
- Bestehende Reklamationen: Werden ueber die ID in der URL geladen (
/qms/reklamation.html?id=rek_xxx).
RUDI Chat-Integration
Ueber den Button “Mit RUDI bearbeiten” (unten rechts) oeffnet sich das Chat-Panel mit vollem Reklamationskontext. Quick-Actions:
- Reklamationsformular erstellen – Formblatt (FB) als DOCX mit QMS-Vorlage
- Stellungnahme verfassen – Verfahrensanweisung (VA) als DOCX an den Kunden
- Korrekturmassnahmen – Arbeitsanweisung (AA) mit Ursache, Massnahme, Verantwortlichem, Frist (IFS 5.7.3)
- 8D-Report – Formblatt als DOCX
- Was tun? – Uebersicht der erforderlichen QMS-Dokumente
RUDI nutzt die vorhandenen Reklamationsdaten automatisch und erstellt Dokumente mit der Regio Frucht QMS-Vorlage (Kopf-/Fusszeile, Dok-ID, Version).
Bilder-Vorschau
Hochgeladene Bilder (JPG, PNG, WebP) werden als Thumbnail-Galerie angezeigt. Ein Klick oeffnet die Lightbox mit Vollbild-Ansicht, Pfeil-Navigation (auch per Tastatur), und optionalem Download-Button.
Dateispeicherung
Dateien aus E-Mail-Analysen werden zunaechst in einem Staging-Bereich zwischengespeichert. Beim Speichern der Reklamation werden sie automatisch in den permanenten Ordner (~/uploads/reklamationen/{rek_id}/) verschoben und mit der Reklamation verknuepft.
Bildanalyse (Claude Vision)
RUDI kann Bilder aus Reklamationen visuell analysieren (Tool: reklamation_bild_analysieren). Dabei werden Qualitaetsmaengel wie Druckstellen, Schimmel, Verfaerbungen, Fremdkoerper oder Verpackungsschaeden erkannt.
- Bilder > 4 MB werden automatisch verkleinert (max. 2000×2000px, JPEG 80%)
- Max. 4 Bilder pro Analyse, Bilder < 1 KB werden uebersprungen (Logos/Icons)
- Bildverkleinerung via sharp (serverseitig)
- Aufruf ueber Chat-Panel: “Was ist auf den Bildern zu sehen?” oder Quick-Action Chips
Reklamationssuche (ChromaDB)
Historische Reklamationen werden in der Vektordatenbank indexiert. Das Tool reklamationen_suche findet aehnliche Faelle, z.B. “Druckstellen bei Erdbeeren” oder “Temperaturproblem Lieferung”. Hilfreich um Muster zu erkennen.
IFS-Referenz
Vektordatenbank & Semantische Suche
RUDI nutzt eine Vektordatenbank (ChromaDB) kombiniert mit Google Gemini Embedding 2, um Dokumente, Bilder und Reklamationen inhaltlich durchsuchbar zu machen – nicht nur nach Stichworten, sondern nach Bedeutung.
Wie funktioniert das?
Jedes Dokument, Bild oder jeder Text wird in einen Zahlenvektor (768 Zahlen) umgewandelt. Aehnliche Inhalte erzeugen aehnliche Vektoren. So findet die Suche nach “kaputter Riemen” auch ein Foto eines gerissenen Riemens – selbst wenn das Foto nicht beschriftet ist.
Suchprozess am Beispiel
Szenario: Du suchst Bilder von einem kaputten Riemen an der GS 10.
Schritt 1: Du fragst RUDI
Du: "Zeig mir Bilder von kaputten Riemen"
Schritt 2: Text wird zum Vektor
Gemini Embedding API wandelt deinen Text in 768 Zahlen um:
"kaputter Riemen" → [0.21, -0.39, 0.11, 0.85, ...]
Schritt 3: ChromaDB vergleicht
Dein Vektor wird mit allen gespeicherten Medien-Vektoren verglichen:
| Gespeichertes Medium | Score | Ergebnis |
|---|---|---|
| Foto: gerissener Riemen GS 10 | 0.87 | Treffer |
| Video: Riemenwechsel-Anleitung | 0.71 | Treffer |
| Foto: verschlissenes Messer | 0.31 | – |
| Foto: saubere Maschine | 0.12 | – |
Schritt 4: RUDI antwortet
RUDI: "Ich habe 2 passende Medien gefunden:
- Bild: gerissener_riemen.jpg (GS 10, Kategorie: Fehler)
- Video: riemenwechsel.mp4 (GS 10, Kategorie: Wartung)"
Warum findet die Suche auch Bilder OHNE Beschreibung?
Gemini Embedding 2 ist multimodal – es versteht Text UND Bilder gleichzeitig. Wenn du ein Foto hochlaedst, erzeugt Gemini einen Vektor der den visuellen Inhalt repraesentiert. Dieser Vektor liegt im selben Raum wie Text-Vektoren:
Bild hochladen Text-Suche
| |
v v
Gemini "sieht" das Bild Gemini "versteht" den Text
| |
v v
Vektor: [0.22, -0.40, ...] Vektor: [0.21, -0.39, ...]
| |
+----------- aehnlich! ----------+
|
v
TREFFER!
Was passiert beim Bild-Upload?
1. Bild wird hochgeladen
|
v
2. Datei gespeichert in ~/maschinen/medien/{id}/{YYYY-MM}/
|
v
3. Gemini Vision analysiert das Bild automatisch
→ "Foto zeigt ausgefransten Antriebsriemen mit Verschleissspuren"
|
v
4. Beschreibung wird in Datenbank gespeichert
|
v
5. Zwei Embeddings werden erzeugt:
a) Bild-Vektor (multimodal, vom Foto selbst)
b) Text-Vektor (von der Auto-Beschreibung)
|
v
6. RUDI weiss jetzt was auf dem Bild ist
und kann es per Textsuche finden
OCR-Fallback (seit 27.03.2026)
Gescannte PDFs (Bilder statt Text) werden automatisch per Tesseract OCR gelesen. Der Fallback greift systemweit — egal in welchem Modul oder Chat ein PDF hochgeladen wird.
| Wo | Vorher | Nachher |
|---|---|---|
Maschinen-Anleitungen (vectordb.py) | Gescannte Seiten uebersprungen | OCR-Fallback pro Seite, Text in ChromaDB |
Anleitungs-Analyse (analyse_anleitung.py) | Kein Text → Fehler | OCR-Fallback, Wartungsplaene auch aus Scans |
Chat read_file (tools.js) | "Kein extrahierbarer Text" | OCR via ocr.py CLI, Text angezeigt |
Ablauf: pdfplumber versucht Text zu extrahieren (schnell). Nur wenn kein/wenig Text gefunden wird (<50 Zeichen/Seite), startet Tesseract OCR als Fallback (2-5 Sek/Seite, max 20 Seiten).
Force-Reprocessing: Bereits verarbeitete Anleitungen koennen mit force=true erneut
verarbeitet werden (z.B. nach OCR-Update oder wenn ein Scan beim ersten Mal nicht erkannt wurde).
ChromaDB Collections
| Collection | Inhalt | Embedding-Typ |
|---|---|---|
pipeline_dokumente | Lieferscheine, Rechnungen (OCR-Text) | Text |
maschinen_anleitungen | Bedienungsanleitungen (seitenweise, mit OCR-Fallback) | Text + Visuell |
maschinen_medien | Maschinenfotos und -videos | Bild + Text |
qms_reklamationen | Kundenreklamationen | Text |
wareneingang_bilder | Wareneingangsdoku (vorbereitet) | – |
Kosten
| Aktion | Kosten pro Stueck | Bei 30/Tag |
|---|---|---|
| Text embedden | ~$0.00003 | ~$0.03/Monat |
| Bild embedden | ~$0.00005 | ~$0.05/Monat |
| Bild beschreiben (Vision) | ~$0.001 | ~$0.90/Monat |
| Suche (pro Anfrage) | ~$0.00003 | vernachlaessigbar |
Gesamt bei intensiver Nutzung: unter $1/Monat.
Maschinenmanagement
Das Maschinenmodul verwaltet Produktionsmaschinen (Schneiden, Waschen, Verpacken, Kuehlung) mit Stammdaten, Bedienungsanleitungen, Wartungsplaenen und Medien. Erreichbar unter /maschinen/.
Funktionen
- Maschinenakte – Stammdaten, Hersteller, Standort, Kategorie, Inbetriebnahme
- Bedienungsanleitungen – PDF hochladen, seitenweise in ChromaDB indexiert, per RUDI durchsuchbar
- Wartungsplaene – automatisch aus Anleitung extrahiert (Claude) oder manuell erstellt
- Wartungsprotokolle – Dokumentation durchgefuehrter Wartungen
- Taegliche Wartungsueberwachung – systemd Timer prueft faellige Wartungen
Maschinen-Wissen
RUDI speichert maschinenspezifisches Wissen dauerhaft – Tipps, Warnungen und Erfahrungswerte die nicht in der Bedienungsanleitung stehen.
Du im Chat: "Merk dir: Beim Riemenwechsel an der GS 10
muss die Spannung auf 3,5 Nm gestellt werden"
|
v
RUDI speichert als Hinweis:
Typ: Tipp
Inhalt: "Beim Riemenwechsel Spannung auf 3,5 Nm einstellen"
|
v
Bei jeder zukuenftigen Frage zur GS 10:
RUDI laedt automatisch alle aktiven Hinweise
und beruecksichtigt sie in der Antwort.
Hinweise-Typen: Tipp (Praxistipp), Warnung (Sicherheit), Fehler (bekannte Probleme), Prozess (Arbeitsablaeufe). Max. 20 aktive Hinweise pro Maschine werden in den Chat-Kontext geladen.
Medien & Dokumentation
Jede Maschine kann mit Bildern, Videos und Dokumenten angereichert werden:
- Bilder (JPG, PNG, WEBP) – automatische Beschreibung via Gemini Vision, multimodal embedded in ChromaDB
- Videos (MP4, MOV, WebM) – Beschreibung wird als Text embedded, max. 100 MB
- Upload ueber Detailseite oder Chat
- Kategorien: Fehler, Wartung, Zustand, Sonstiges
Medien sind ueber die semantische Suche auffindbar: "Zeig mir Bilder von kaputten Riemen" → RUDI durchsucht ChromaDB und findet passende Fotos (siehe Semantische Suche).
Fuhrparkmodul
Das Fuhrparkmodul verwaltet alle 11 Firmenfahrzeuge mit Stammdaten, TUeV-Terminen, Wartungsplaenen, KM-Eintraegen, Dokumenten und Fahrerkarten. Datenbasis: SQLite unter ~/fuhrpark/fuhrpark.db.
Fahrzeugtypen
- kuehl_lkw – Kuehl-LKW (Fiat Ducato 3,5t, MFTBC 7,5t, MAN TGL 12t)
- lkw – LKW ohne Kuehlung (Mercedes 308 D)
- e_auto – Elektrofahrzeuge (Tesla Model Y, Mercedes EQE 500) – keine AU noetig
- pkw – PKW (Mercedes AMG C 63 S, Audi Q7, Audi S3)
TUeV-Verwaltung
TUeV-Faelligkeiten werden im Format MM/YYYY gespeichert. Die API liefert Fahrzeuge nach TUeV-Dringlichkeit sortiert. Bremswerte aus der HU werden als JSON in der TUeV-Historie gespeichert.
Wartungsplanung
Wartungsplaene haben zeit- und/oder KM-basierte Intervalle. Bei Protokolleintrag wird naechste_faellig automatisch berechnet und km_stand im Fahrzeug aktualisiert.
Dateipfade
- Datenbank:
~/fuhrpark/fuhrpark.db - Schema:
~/fuhrpark/schema.sql - Seed-Script:
~/fuhrpark/seed.js(einmalig, 11 Fahrzeuge) - Dokumente:
~/fuhrpark/dokumente/{fahrzeug_id}/ - Fahrerkarten:
~/fuhrpark/dokumente/{fahrzeug_id}/fahrerkarten/ - Tacho-Uploads:
~/fuhrpark/dokumente/tacho/ - Tacho-Parser-Binary:
~/fuhrpark/bin/dddparser - Lib:
~/rudi-chat/lib/fuhrpark-db.js,~/rudi-chat/lib/tacho-parser.js,~/rudi-chat/lib/tacho-violations.js - Route:
~/rudi-chat/routes/fuhrpark.js
API-Endpunkte
Alle Endpunkte sind unter /chat/api/ erreichbar (via Nginx Proxy). Basis: https://rudi-regiofrucht.de
Chat
| Methode | Route | Beschreibung |
|---|---|---|
| POST | /chat/api/chat | Haupt-Chat (SSE Streaming). Body: {message, chatId} |
| GET | /chat/api/chats | Alle Chats auflisten. Optional: ?filter=qms|recurring|chat |
| GET | /chat/api/chats/:id | Einzelnen Chat laden |
| PATCH | /chat/api/chats/:id | Chat umbenennen |
| DELETE | /chat/api/chats/:id | Chat in Papierkorb verschieben (soft delete). ?permanent=true fuer endgueltiges Loeschen |
| GET | /chat/api/chats/trash/list | Papierkorb auflisten |
| POST | /chat/api/chats/trash/restore/:id | Chat aus Papierkorb wiederherstellen |
| DELETE | /chat/api/chats/trash/empty | Papierkorb komplett leeren |
Dateien
| Methode | Route | Beschreibung |
|---|---|---|
| POST | /chat/api/upload | Datei-Upload (Multer, max 50 MB) |
| POST | /chat/api/transcribe | Audio-Transkription (Whisper) |
| GET | /chat/api/view?path=...&download=1 | Datei anzeigen/herunterladen |
QMS
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/qms/dashboard | Dashboard-Daten (Stats, Kapitel, Ordner, Annotations) |
| GET | /chat/api/qms/annotations | Alle Annotations |
| PUT | /chat/api/qms/annotations/:ref | Annotations fuer Ref aktualisieren |
| POST | /chat/api/qms/annotations/:ref/task | Neue Aufgabe erstellen |
| PATCH | /chat/api/qms/annotations/:ref/task/:id | Aufgabe aktualisieren |
| DELETE | /chat/api/qms/annotations/:ref/task/:id | Aufgabe loeschen |
| GET | /chat/api/qms/recurring | Wiederkehrende Aufgaben |
| POST | /chat/api/qms/recurring | Neue Recurring-Aufgabe |
| POST | /chat/api/qms/recurring/:id/complete | Aufgabe erledigen |
| PATCH | /chat/api/qms/recurring/:id | Aufgabe bearbeiten |
| DELETE | /chat/api/qms/recurring/:id | Aufgabe loeschen |
| POST | /chat/api/qms/upload | QMS-Datei-Upload (max 200 Dateien, Ordner-Upload) |
| GET | /chat/api/qms/folders | QMS-Ordnerliste (fuer Upload-Zielwahl) |
Reklamationen
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/qms/reklamationen | Alle Reklamationen auflisten |
| POST | /chat/api/qms/reklamationen | Neue Reklamation anlegen. Body: {kunde, datum, produkt, charge, reklamationsgrund, beschreibung, sofortmassnahme, status} |
| PUT | /chat/api/qms/reklamationen/:id | Reklamation aktualisieren |
| DELETE | /chat/api/qms/reklamationen/:id | Reklamation loeschen |
| POST | /chat/api/qms/reklamationen/:id/dateien | Dateien (Fotos, Dokumente) zu Reklamation hochladen |
| POST | /chat/api/qms/parse-email | E-Mail (.eml/.msg) oder Bilder analysieren. Multipart-Upload. Gibt vorausgefuellte Felder + _meta.stagingId zurueck. Dateien werden in Staging gespeichert. |
| POST | /chat/api/qms/reklamationen/:id/claim-staging | Staging-Dateien in Reklamation uebernehmen. Body: {stagingId}. Verschiebt Dateien von Staging nach uploads/reklamationen/{id}/ |
Pipeline
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/pipeline/stats | Dashboard-Statistiken (heute, gesamt, fehler, offen) |
| GET | /chat/api/pipeline/dokumente | Dokumentenliste. Filter: ?kategorie=&status=&lieferant=&von=&bis= |
| GET | /chat/api/pipeline/dokumente/:id | Einzeldokument mit extrahierten Daten |
| POST | /chat/api/pipeline/dokumente/:id/status | Status aendern. Body: {status: "geprueft"} |
| POST | /chat/api/pipeline/dokumente/:id/zuordnen | LS/RE manuell zuordnen. Body: {lieferschein_id} |
| GET | /chat/api/pipeline/abgleich | LS/RE-Abgleich-Ergebnisse |
| GET | /chat/api/pipeline/alerts | Aktuelle Meldungen (Fehler, offene Rechnungen) |
| POST | /chat/api/pipeline/upload | Dokument hochladen (multipart, Feld: datei) → eingang/ |
| POST | /chat/api/pipeline/upload-personal | Personaldokument hochladen (nur Admin) → eingang_personal/ |
| POST | /chat/api/pipeline/reprocess/:id | Fehlgeschlagenes Dokument erneut verarbeiten |
Personal-Routen (nur Admin)
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/pipeline/personal/mitarbeiter | Mitarbeiterliste (aktive) |
| GET | /chat/api/pipeline/personal/mitarbeiter/:id | Personalakte mit allen Dokumenten |
| POST | /chat/api/pipeline/personal/mitarbeiter | Neuen Mitarbeiter anlegen |
| GET | /chat/api/pipeline/personal/dokumente | Alle Personaldokumente (gefiltert) |
| GET | /chat/api/pipeline/personal/erinnerungen | Ablaufende Dokumente (Belehrungen etc.) |
Fuhrpark
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/fuhrpark | Alle Fahrzeuge (aktive). Filter: ?typ=kuehl_lkw|pkw|e_auto|lkw. Sortiert nach TUeV-Dringlichkeit. |
| GET | /chat/api/fuhrpark/stats | Uebersicht: {gesamt, tuev_dringend, wartung_faellig} |
| GET | /chat/api/fuhrpark/tuev-faellig | Fahrzeuge mit TUeV in naechsten N Wochen. Filter: ?wochen=6 |
| GET | /chat/api/fuhrpark/:id | Einzelfahrzeug mit wartungsplaene, letzte_protokolle, letzte_km_eintraege, dokumente, tuev_historie, fahrerkarten |
| POST | /chat/api/fuhrpark | Fahrzeug anlegen. Pflicht: kennzeichen, fahrzeug |
| PUT | /chat/api/fuhrpark/:id | Fahrzeug aktualisieren |
| DELETE | /chat/api/fuhrpark/:id | Fahrzeug deaktivieren (Soft-Delete, aktiv=0) |
| POST | /chat/api/fuhrpark/:id/tuev | TUeV-Eintrag hinzufuegen. Body: {datum, pruefstelle, pruefer, ergebnis, bremswerte, tuev_faellig_neu} |
| GET | /chat/api/fuhrpark/:id/tuev | TUeV-Historie des Fahrzeugs |
| GET | /chat/api/fuhrpark/:id/wartung | Wartungsplaene des Fahrzeugs |
| POST | /chat/api/fuhrpark/:id/wartung | Wartungsplan anlegen. Body: {bezeichnung, kategorie, intervall_tage, intervall_km, ...} |
| PUT | /chat/api/fuhrpark/:id/wartung/:planId | Wartungsplan bearbeiten |
| DELETE | /chat/api/fuhrpark/:id/wartung/:planId | Wartungsplan loeschen (inkl. Protokolle) |
| POST | /chat/api/fuhrpark/:id/protokoll | Wartung protokollieren. Body: {wartungsplan_id, durchgefuehrt_am, km_stand, werkstatt, kosten, ergebnis} |
| POST | /chat/api/fuhrpark/:id/km | KM-Stand eintragen. Body: {km_stand, datum, quelle}. Plausibilitaetspruefung. |
| GET | /chat/api/fuhrpark/:id/km | KM-Verlauf. Filter: ?limit=50 |
| POST | /chat/api/fuhrpark/:id/dokument | Dokument hochladen (PDF, JPG, PNG; 50 MB). Felder: datei, typ, beschreibung |
| DELETE | /chat/api/fuhrpark/:id/dokument/:docId | Dokument loeschen (DB + Datei) |
| GET | /chat/api/fuhrpark/:id/dokument/:docId/view | Dokument anzeigen/herunterladen |
| POST | /chat/api/fuhrpark/:id/fahrerkarte | Fahrerkarte hochladen (.ddd, 10 MB). Felder: datei, fahrer_name, kartennummer |
| GET | /chat/api/fuhrpark/:id/fahrerkarte | Fahrerkarten des Fahrzeugs |
| POST | /chat/api/fuhrpark/sync-gps | GPS-Sync (501 Not Implemented – fuer kuenftige FindCar-Integration) |
Tacho-Auswertung
Digitale Tachograph-Auswertung (.ddd-Dateien). Frontend: /fuhrpark/tacho.html. Parser-Binary: ~/fuhrpark/bin/dddparser. Gespeichert unter ~/fuhrpark/dokumente/tacho/. Verstoesspruefung nach EU VO 561/2006.
| Methode | Route | Beschreibung |
|---|---|---|
| POST | /chat/api/fuhrpark/tacho/parse | DDD-Datei hochladen (max 200 MB). Felder: datei, fahrzeug_id (opt). Auto-Detect Fahrerkarte/VU. Response: {auswertung_id, type, fahrer_name, verstoesse_count, zusammenfassung, tagesauswertung} |
| GET | /chat/api/fuhrpark/tacho/auswertungen | Alle Tacho-Auswertungen. Filter: ?fahrzeug_id=&fahrer_name=&limit= |
| GET | /chat/api/fuhrpark/tacho/stats | Tacho-Statistik: {auswertungen_gesamt, verstoesse_gesamt, verstoesse_nach_schwere} |
| GET | /chat/api/fuhrpark/tacho/verstoesse | Verstoesse-Liste. Filter: ?fahrer_name=&schwere=leicht|schwer|sehr_schwer&typ=&von=&bis= |
| GET | /chat/api/fuhrpark/tacho/fahrer/:name | Alle Auswertungen + Verstoesse fuer einen Fahrer |
| GET | /chat/api/fuhrpark/tacho/auswertung/:id | Einzelne Auswertung mit parsed_data + Verstoessen |
| DELETE | /chat/api/fuhrpark/tacho/auswertung/:id | Auswertung loeschen (DB-Eintraege + Datei) |
Team-Chat
Interner Messenger unter /team/ — Direktnachrichten + Gruppen, Medienversand, Sprachnachrichten, automatische Uebersetzung (DE/RO) und WebSocket-Echtzeit.
Seiten
| Seite | Pfad | Funktion |
|---|---|---|
| Konversationsliste | /team/ | Alle Chats, Suche, Ungelesen-Badges, neuer Chat per FAB |
| Nachrichtenansicht | /team/chat.html?id=CONV_ID | Vollbild-Chat, Medien, Sprachnachricht, Antworten, Kontextmenu |
| Profil | /team/profil.html | Avatar, Status-Text, Sprache (DE/RO) |
Features
- Medien: Bilder (Canvas-Resize auf max. 1920px), Dateien, Sprachnachrichten (MediaRecorder, iOS mp4/webm Fallback)
- Uebersetzung: content_translated-Feld: Haupttext in Nutzersprache, Original klappbar
- Antworten: reply_to-Vorschau in Bubble + Compose-Bar
- Bearbeiten/Loeschen: per Long-Press-Kontextmenu (eigene Nachrichten, Bearbeiten max. 15 Min)
- WebSocket: Reconnect mit exp. Backoff (1s/2s/.../30s), Ping alle 25s
- Online-Status: gruener Punkt am Avatar, Header-Status in DM
- Bottom-Nav: Home / Chat / Ideen / Mehr — einheitlich auf allen 3 Seiten
API-Basis
/chat/api/team-chat/ (Nginx Proxy → :3456/)
Kommunikation (E-Mail & Kalender)
Das Kommunikationsmodul unter /kommunikation/ integriert E-Mail und Kalender ueber die Microsoft Graph API mit zwei Shared Mailboxen.
Mailboxen
| Mailbox | Adresse | Zweck | Senden |
|---|---|---|---|
| RUDI | rudi@regiofrucht.de | Allgemeine Kommunikation | Ja (direkt) |
| QMS | qms@regiofrucht.de | Reklamationen, Audits, Lieferanten | Nur Entwuerfe (User sendet in Outlook) |
Authentifizierung
Azure App Registration mit Client Credentials Flow (app-only, kein User-Login). Berechtigungen: Mail.Read, Mail.ReadWrite, Mail.Send, Calendars.Read, Calendars.ReadWrite, User.Read.All. Die Berechtigungen gelten tenant-weit fuer beide Mailboxen. Credentials in /etc/environment: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, RUDI_MAILBOX, QMS_MAILBOX.
E-Mail-Tab (rudi@)
Layout: Outlook-Style 3-Spalten (Ordner-Sidebar | E-Mail-Liste | Lesebereich). Ordner: Posteingang, Gesendet, Entwuerfe, Papierkorb, Junk, Archiv. Features: Datum-Gruppierung (Heute/Gestern/Woche/Aelter), CID-Inline-Bilder, Signatur (global + individuell), Antworten/Weiterleiten, Sync-Button, Ungelesen-Filter.
Signatur: Gespeichert in auth.db (Tabelle email_signatures). Global (Admin) + individuell (pro User). Wird serverseitig an ausgehende E-Mails angehaengt. API: GET/PUT /chat/api/email/signatur, GET/PUT /chat/api/email/signatur/global.
E-Mail-Sync: Polling alle 5 Minuten via Graph API Delta Query. Neue/geaenderte E-Mails werden in die lokale SQLite-DB gespeichert (AES-256-GCM verschluesselt). Geloeschte oder verschobene E-Mails werden ueber @removed-Marker aus der Delta-Response erkannt und automatisch aus dem lokalen Cache entfernt. Bei verwaisten Eintraegen (z.B. vor dem Fix geloescht) werden beim manuellen Sync (POST /chat/api/email/sync) alle DB-Eintraege gegen den Live-Inbox abgeglichen und nicht mehr vorhandene Mails bereinigt.
Kalender-Tab
Wochenansicht mit Zeitraster (6:00–21:00 Uhr, 48px/Stunde). Mitarbeiter-Kalender: Checkbox-Liste in der Sidebar, farbcodiert (blau/gruen/orange/lila/rot). Mehrere Kalender gleichzeitig als Overlay. Termine: Erstellen per Klick auf Zeitslot oder Button, Bearbeiten/Loeschen per Klick auf Event. Zeitzonen: Europe/Berlin.
QMS-E-Mail (qms@)
Sicherheitskonzept: RUDI darf ueber qms@ KEINE E-Mails direkt senden. Sende-Blockierung auf Graph-API-Ebene (assertSendAllowed). Nur Entwuerfe (Drafts) koennen erstellt werden. User sendet in Outlook.
Dashboard-Integration: Im QMS-Dashboard (/qms/) zeigt eine kompakte Sektion die letzten QMS-E-Mails + Ungelesen-Badge + Links zu Outlook Inbox und Entwuerfe.
API-Endpoints (unter /chat/api/qms/email/, geschuetzt mit requireModule('qms')):
| Methode | Endpoint | Beschreibung |
|---|---|---|
| GET | /chat/api/qms/email/inbox | QMS-Posteingang (lokale DB) |
| GET | /chat/api/qms/email/inbox/:id | Einzelne QMS-E-Mail (mit CID-Bilder-Auflosung) |
| GET | /chat/api/qms/email/stats | Ungelesen-Count, letzte E-Mail |
| GET | /chat/api/qms/email/drafts | Offene Entwuerfe in qms@ |
| POST | /chat/api/qms/email/draft | Entwurf erstellen (an, betreff, text) |
| POST | /chat/api/qms/email/draft/:id/send | Entwurf absenden (User-Aktion) |
| POST | /chat/api/qms/reklamationen/:id/email-entwurf | Reklamations-Antwort als Entwurf |
| POST | /chat/api/qms/email/sync | Manueller QMS-Mail-Sync |
RUDI-Chat-Tools
| Tool | Mailbox | Beschreibung |
|---|---|---|
email_inbox | rudi@ | E-Mails anzeigen/filtern |
email_senden | rudi@ | E-Mail senden (mit Bestaetigung) |
email_anhang_lesen | rudi/br/info@ | Anhaenge lesen: detail="summary" (Haiku-Kurzfassung, gecached) oder detail="volltext" (Rohtext aller Seiten, Sonnet Vision bei Scan-PDFs/Bildern). PFLICHT bei konkreten Zahlen/Mengen/Preisen/Artikelnummern. |
qms_email_inbox | qms@ | QMS-Posteingang lesen |
qms_email_entwurf | qms@ | Entwurf erstellen (kein Senden!) |
kalender_termine | rudi@ | Termine anzeigen (eigen + Mitarbeiter) |
kalender_termin_erstellen | rudi@ | Termin anlegen mit Teilnehmern |
Technische Details
- Backend:
lib/microsoft-graph.js(Multi-Mailbox: MAILBOXES-Registry, resolveMailbox(), Draft-Funktionen, Sende-Blockierung) - Datenbank:
~/email/email.db(SQLite, WAL-Modus, Spaltemailboxfuer Trennung, QMS-IDs mit Prefixqms:) - Polling: Alle 5 Min per Delta-Query. RUDI bei t=0, QMS versetzt bei t+2.5min. QMS: nur Metadaten (kein Body).
- Nginx: Dedizierte Location-Bloecke:
/chat/api/email/,/chat/api/kalender/. QMS-E-Mail laeuft ueber/chat/api/qms/. - Signatur: Tabelle
email_signaturesinauth.db. ID__global__= Firmen-Signatur, ID = user_id = individuelle Signatur.
Einkauf-Dashboard
Das Einkauf-Dashboard unter /einkauf/ ist das Eingangsmodul fuer Wareneingang, Chargen und Lieferantenmanagement. Es folgt dem Standard-Design-System mit Apple Glasmorphism, Dark/Light Mode und eingebettetem RUDI Chat-Panel.
Wareneingang
Vollstaendige Seite unter /einkauf/wareneingang.html. Erfassung und Pruefung von Wareneingaengen mit Lieferant, Charge, Typ (Bio/Standard/Packaging) und Status-Workflow (neu → geprueft → eingelagert / abgelehnt). Includes Accordion-Liste, Erfassungs-Modal mit Drag&Drop-Bild-Upload, client-seitiger Bild-Komprimierung (max 2560×1440, 85% JPEG), Duplikat-Check fuer Chargen, LocalStorage-Autosave und Excel-Export.
Phase-3-Erweiterungen (2026-04-27): Country-of-Origin-Pflichtfeld (Feature-Flag we_country_pflicht) mit Dropdown (30 Laender), Auto-Vorbefuellung via GET /vorbereiten nach Lieferant-Auswahl · Quelle-Badge zeigt ob Country aus Avis, Lieferanten-Default oder manuell · Vorgang-Info-Box: zeigt offene Vorgaenge, Dropdown bei mehreren, "Neuer Vorgang" wenn keiner · Avis-Positionen-Box (collapsible): "Alle uebernehmen" matcht Rohwaren automatisch · Vision-Live-Warnung: nach Bild-Upload Polling alle 5s, gelbe/rote Box bei Maengeln (Feature-Flag we_vision_warnung) · Quality-Filter Dropdown (Alle/OK/Mangel/Gesperrt) · Quality-Badge als neue Spalte in der Liste · capture="environment" fuer direkten Smartphone-Kamera-Aufruf.
Features: Filter nach Typ/Status/Quality/Datum/Suche · Thumbnails mit Lightbox · RUDI Chat-Panel (Modul: einkauf) · Detail-Link zu /einkauf/detail.html?id=X
Wareneingang Detail
Detailseite /einkauf/detail.html?id=X mit 2-Spalten-Layout (Main + 340px Sidebar). Laedt Daten von GET /chat/api/einkauf/wareneingang/{id}.
Main-Bereich: Stammdaten-Card (Lieferant, Datum, Typ, Status) · Daten-Card (Charge, Rohwaren als Chips, Notizen) · Bilder-Galerie mit Tabs (Lieferscheine / Waren), Thumbnail-Grid, Lightbox · Direkter Bild-Upload je Tab · KI-Bildanalyse-Card (MIB-Audit Korrektur 4, 2026-04-28): Pro Bild Thumbnail + vision_beschreibung aus wareneingang_bilder + Vision-Status-Badge (done/pending/error). Bei pending: Spinner "Analyse laeuft...". Bei error: graue Box + "Erneut versuchen"-Button (POST /quality-check). Zusammenfassungs-Zeile (X analysiert, Y ausstehend, Z Fehler). Button "Neu analysieren" fuer alle Bilder. Kein Backend-Change noetig: SELECT * liefert bereits vision_status + vision_beschreibung. · OCR-Text-Section (collapsible).
Sidebar (Phase 3): Lieferanten-Info · Chargen-Info · Herkunftsland-Card · Quality-Pruefung-Card: Status-Badge, Maengel-Liste, Button "Neu analysieren" (POST /quality-check), nur sichtbar wenn Feature-Flag we_vision_warnung ON · Vorgang-Card: Vorgang-ID als Link, Belege-Typen-Uebersicht · Soll-Ist-Vergleich-Card (Phase 4 Vorbereitung): bei vorhandener Vorgang-ID ladbar via GET /vorbereiten · Zeitstempel · Sync-Badge.
Edit-Modal (Phase 3 ergaenzt): Herkunftsland-Dropdown (30 Laender) · Herkunftsland wird bei PUT /wareneingang/{id} als herkunftsland_iso mitgesendet.
API-Calls der Detailseite: GET /wareneingang/{id}, PUT /wareneingang/{id} (Edit + Status + herkunftsland_iso), DELETE /wareneingang/{id}, POST /wareneingang/{id}/bilder, DELETE /wareneingang/{id}/bilder/{bildId}, POST /wareneingang/{id}/quality-check (Phase 3)
API-Pfade (alle ueber /chat/api/einkauf/):
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/statistik | Statistik: heute, offen, woche (Felder als Zahlen) |
| GET | /chat/api/einkauf/wareneingang | Liste. Query: q, von, bis, typ, status, charge. Antwort: { items, stats } |
| GET | /chat/api/einkauf/wareneingang/vorbereiten | Phase 3 NEU: Vorbefuellung fuer Wareneingang-Erfassung. Query: lieferant_id (Pflicht), datum (opt.). Antwort: { lieferant, vorschlag_charge, vorschlag_typ, vorschlag_country, country_quelle, offene_vorgaenge[], avis_positionen[], letzte_lieferungen[], lieferant_default_country, warnungen[] }. requireAuth + requireModule('einkauf'). |
| POST | /chat/api/einkauf/wareneingang | Neuer Eintrag. Body: lieferant_id, datum, typ, chargennummer, notizen, rohwareIds[], herkunftsland_iso (Pflicht wenn Feature-Flag we_country_pflicht aktiv), vorgang_id (opt., auto-verlinkt). Antwort: { id, status, vorgang_id, vorgang_auto_angelegt }. Bei mehreren Vorgang-Kandidaten: 422 mit Kandidaten-Liste. |
| PATCH | /chat/api/einkauf/wareneingang/:id | Teilupdate (z.B. Status aendern) |
| DELETE | /chat/api/einkauf/wareneingang/:id | Loeschen |
| POST | /chat/api/einkauf/wareneingang/:id/bilder | Bild hochladen (multipart). Felder: dateien[], typ (lieferschein|ware). Triggert Vision-Embedding + auto Quality-Check wenn alle Bilder done. |
| POST | /chat/api/einkauf/wareneingang/:id/quality-check | Phase 3 NEU: Vision-Live-Qualitaetsanalyse. Body: { prompt_zusatz?: string }. Antwort: { status, quality_status, bio_sperre, bio_sperre_grund, ergebnis: { maengel[], gesamteindruck } }. Speichert in auto_validierung_json + cockpit_auffaelligkeiten. Bei typ='bio' + Mangel und Feature-Flag bio_quality_gate ON: setzt quality_status='gesperrt', Cockpit-Eintrag 'bio_konflikt', Audit-Log 'bio_sperre'. Feature-Flag we_vision_warnung muss ON sein (sonst 403). requireAuth + requireWrite + requireCsrf + requireModule('einkauf'). |
| POST | /chat/api/einkauf/wareneingang/:id/bio-freigabe | MIB-Audit Korrektur 2 NEU: BIO-Sperre aufheben. Body: { grund: string (min 10 Zeichen) }. Nur bei quality_status='gesperrt' ausfuehrbar (sonst 422). Setzt quality_status='ok', schreibt sperre_freigabe_durch/grund/am in auto_validierung_json, Audit-Log 'bio_freigabe'. Auth: requireAuth + requireWrite + requireCsrf + (role='admin' ODER module='qms') — einkauf-Rolle allein darf NICHT freigeben (IFS-Pflicht). PUT /wareneingang/:id liefert 423 wenn quality_status='gesperrt' und Status-Aenderung versucht wird. |
| GET | /chat/api/einkauf/wareneingang/export | Excel-Export mit denselben Filtern wie Liste |
| GET | /chat/api/einkauf/lieferanten | Lieferantenliste (Top-5 haeufigste zuerst) |
| GET | /chat/api/einkauf/rohwaren | Rohwaren-Liste. Query: gruppiert=true liefert Objekt nach Kategorie |
| GET | /chat/api/einkauf/charge/vorschlag | Auto-Vorschlag. Query: typ, datum |
Vorgangsmodell – Phase 4: Auto-Reklamation Solvega (Schatten-Modus)
Automatische Soll/Ist-Diff-Detektion mit Claude Vision fuer Lieferanten-Handschrifterkennung auf Albarane. 4-Wochen-Schatten-Modus: Vorschlaege landen in DB, kein Mail-Versand. Mensch gibt frei.
Solvega-Spezifik: Vereinbarung Regio Frucht ↔ Solvega: Regio Frucht wiegt jede Lieferung, teilt Ist-Mengen mit, Solvega korrigiert die Rechnung entsprechend. Mengen werden handschriftlich auf das Albaran notiert. Vision liest Soll (gedruckt) + Ist (Handschrift) automatisch.
Neue Dateien:
~/rudi-chat/lib/vision-handschrift.js— Claude Sonnet Vision fuer handschriftliche Mengen-Notizen. API:extractHandschriftMengen(imagePath, opts). Tagesbudget:VISION_HANDSCHRIFT_MAX(default 100 = max ~$0.50/Tag). Robuster JSON-Parser + Regex-Fallback.~/rudi-chat/lib/reklamations-generator.js— Claude Haiku Textgenerierung fuer Reklamationsschreiben. Few-Shot aus historischen Reklamationen. API:generiereReklamationsText({lieferant_name, artikel, soll, ist, diff_kg, diff_pct, preis_pro_einheit}).~/bin/soll-ist-diff-trigger.js— Cron alle 30 Min. Sucht Kandidaten-WEs (7 Tage, kein bestehender Auto-Vorschlag), ruft Vision auf Lieferschein-Bilder auf, berechnet Diff > 2%, speichert Vorschlag inreklamationen+ Cockpit-Eintrag + Audit-Log.~/bin/rechnung-korrektur-check.js— Cron stündlich. Vergleicht eingehende Solvega-Rechnungen mit gemeldeter Ist-Menge. Setztfreigabe_statusauf 'nicht_noetig' (Solvega hat korrigiert) oder 'dringend' (nicht korrigiert).
Feature-Flags: auto_reklamation_solvega (ON = Schatten-Modus) · auto_reklamation_versand (OFF = kein Auto-Versand)
Cron-Datei: /etc/cron.d/auto-reklamation (30 Min Diff-Trigger + 60 Min Rechnung-Check)
Log-Dateien: ~/backups/auto-reklamation.log, ~/backups/rechnung-korrektur.log
Env-Konfiguration: AUTO_REKL_LIEFERANTEN (Komma-Liste), AUTO_REKL_DIFF_PCT (default 2.0), AUTO_REKL_KRITISCH_PCT (default 10.0), VISION_HANDSCHRIFT_MAX (default 100/Tag)
DB-Felder: reklamationen.auto_erstellt=1, .freigabe_status='vorgeschlagen', .ki_vorschlag_json (vision_konfidenz, vorschlag_text, gutschrift_berechnung). cockpit_auffaelligkeiten.typ='gewichtsdiff', .schweregrad='warn'|'kritisch'.
Score-Gate: 4 Wochen Schatten-Modus, mind. 40 Vorschlaege, davon ≥90% akzeptiert → dann Auto-Versand aktivierbar via auto_reklamation_versand=ON
Vorgangsmodell – Phase 4: Lieferanten-Risiko-Score (woechentlich)
Woechentliche automatische Risiko-Bewertung aller aktiven Lieferanten mit Wareneingaengen in den letzten 90 Tagen. Score-Berechnung aus drei Komponenten: Reklamationsquote (50%), Mengen-Abweichungsquote (30%), Vision-Maengel-Quote (20%). Trend-Berechnung (besser/stabil/schlechter) aus Vergleich aktueller 90 Tage vs. vorangehende 90 Tage.
Score-Logik: base_score = (rek_pct * 0.5) + (diff_pct * 0.3) + (vision_pct * 0.2). Kategorie: ≥30 = rot, ≥10 = gelb, sonst gruen.
Neue Dateien:
~/bin/lieferanten-risiko-score.js— Cron Mo 04:00 UTC. Berechnet Risiko-Score fuer alle Lieferanten mit >0 WE in 90 Tagen. Schema-Migration idempotent. Schreibt inlieferanten.risiko_score/risiko_kategorie/risiko_komponenten_json/risiko_trend/risiko_aktualisiert_am.
DB-Schema-Erweiterung (einkauf.db Tabelle lieferanten):
risiko_scoreINTEGER — 0-100risiko_kategorieTEXT — gruen | gelb | rotrisiko_komponenten_jsonTEXT — JSON {wes_90, reks_90, quote_rek_pct, wes_mit_diff_90, quote_diff_pct, wes_mit_vision_mangel_90, quote_vision_pct, prev_score}risiko_trendTEXT — neu | besser | stabil | schlechterrisiko_aktualisiert_amTEXT — ISO-Timestamp des letzten Laufs
Cron-Datei: /etc/cron.d/lieferanten-risiko-score (Mo 04:00 UTC)
Log-Datei: ~/backups/lieferanten-risiko-score.log
Audit-Log: modul=lieferanten-risiko, aktion=woechentlich, after_json={count_rot, count_gelb, count_gruen, top_3_rot, ergebnisse[{id, name, score, kategorie, trend}]}
Briefing-Integration: ~/rudi-chat/lib/briefing.js — build() gibt jetzt einkauf.risiko_lieferanten (rot, max 5), einkauf.top_auffaelligkeiten (offen, max 3), einkauf.offene_rek_vorschlaege (Anzahl auto_erstellt+vorgeschlagen) zurueck. formatRisikoText(einkauf) erzeugt lesbaren Warntext fuer Voice/Chat.
REST-Endpoints:
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/lieferanten/risiko-score | Alle Lieferanten mit Risiko-Score. Query: kategorie=rot|gelb|gruen (opt.). Sortierung: rot zuerst, dann Score desc. Antwort: [{lieferant_id, name, risiko_score, risiko_kategorie, risiko_komponenten, risiko_trend, risiko_aktualisiert_am, anzahl_wes_90, anzahl_reks_90}]. requireAuth + requireModule('einkauf'). |
| GET | /chat/api/einkauf/lieferanten/:id/risiko-historie | Letzte 12 Wochen aus Audit-Log. Antwort: {lieferant_id, name, historie:[{datum, score, kategorie, trend, reks_90, wes_90}]}. requireAuth + requireModule('einkauf'). |
Aktuell (2026-04-27): Solvega Crops = rot (Score 46.9, Rek-Quote 93.8%) · Kraaijeveld BV = gelb (Score 17.8) · GP green produce = gelb (Score 13.6) · Schwehr Georg = kein Score (keine WE in 90 Tagen, implizit gruen)
Vorgangsmodell – Phase 4: Mensch-in-the-Loop UI (Reklamations-Vorschlaege)
Frontend fuer die Pruefung und Freigabe automatisch erzeugter Reklamations-Vorschlaege (Cron alle 30 Min, bin/soll-ist-diff-trigger.js). Seite: /einkauf/reklamationen/.
Features: 4 Tabs (Vorschlaege/Freigegeben/Abgelehnt/Manuell) · Statistik-Kacheln (offene Vorschlaege, ausstehende Gutschriften, rote Lieferanten, letzter Cron-Lauf) · Detail-Modal mit Vision-Beschreibung, editierbarem Vorschlagstext und Gutschrift-Betrag · Freigeben-Button (gruen/grau je nach Feature-Flag) · Ablehnen mit Pflicht-Grund · Risiko-Badge inline bei Lieferant · Konfidenz-Balken · Chat-Sidepanel.
Neue Backend-Endpoints (in routes/einkauf.js):
| Methode | Route | Beschreibung |
|---|---|---|
| POST | /chat/api/einkauf/reklamationen/:id/freigeben | Setzt freigabe_status='freigegeben'. Body: optional {vorschlag_text, gutschrift_betrag, grund}. Prueft Feature-Flag auto_reklamation_versand. Audit-Log. requireAuth + requireWrite + requireCsrf + requireModule('einkauf'). |
| POST | /chat/api/einkauf/reklamationen/:id/ablehnen | Setzt freigabe_status='abgelehnt' + status='abgeschlossen'. Body: {grund} (Pflicht). Audit-Log. requireAuth + requireWrite + requireCsrf + requireModule('einkauf'). |
| GET | /chat/api/einkauf/reklamationen/vorschlaege/statistik | Offene Vorschlaege, Summe Gutschriften, rote Lieferanten, letzter Cron-Lauf. requireAuth + requireModule('einkauf'). |
Schatten-Modus: Feature-Flag auto_reklamation_versand = false (Standard). Bei Freigabe wird Status gesetzt, aber keine Mail versendet. Freigeben-Button zeigt "(Schatten-Modus aktiv)" und ist grau statt gruen.
Dateien: /var/www/html/einkauf/reklamationen/index.html, index.css, index.js
Vorgangsmodell – Phase 4: Risiko-Dashboard UI
Frontend fuer die Uebersicht des Lieferanten-Risiko-Scores. Seite: /einkauf/risiko/.
Features: 3 Ampel-Kacheln (rot/gelb/gruen, klickbar als Filter) · Tabelle aller Lieferanten sortiert nach Score · Mini-Bar-Charts inline fuer Rek-Quote, Diff-Quote, Vision-Mangel · Trend-Pfeil · Detail-Modal mit Score-Verlauf aus Audit-Log · Direkt-Link zu Reklamationen des Lieferanten · Chat-Sidepanel.
Dateien: /var/www/html/einkauf/risiko/index.html, index.css, index.js
Einkauf-Index ergaenzt: Zwei neue Kacheln "KI-Vorschlaege" und "Lieferanten-Risiko" mit animiertem Badge (rot wenn Vorschlaege offen / rote Lieferanten vorhanden).
Einkauf – Avis-Pipeline
Seite /einkauf/avis.html — Verwaltung avisierter Wareneingaenge. Zeigt alle vorab gemeldeten Lieferungen mit Status-Workflow (avisiert → geliefert → geprueft) und Soll/Ist-Abgleich.
Features: Stat-Kacheln (Gesamt/Geliefert/Geprueft/Abweichungen, interaktiv als Filter) · Status-Filter-Buttons · Lieferant-Dropdown-Filter · Datumsbereich-Filter (Standard: letzte 30 Tage) · Klick auf Zeile → /einkauf/avis-detail.html?id=X · Modal "Neues Avis" mit Lieferant-Dropdown, Datum und dynamischer Positionen-Tabelle · Ampel-Zusammenfassung (gruen=OK, orange=Warnung, rot=Fehler) · Status-Badges (avisiert=gelb, geliefert=blau, geprueft=gruen) · RUDI Chat-Panel (Modul: einkauf) · escHtml XSS-Schutz · Toast-System
API-Pfade (alle ueber /chat/api/einkauf/):
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/avis | Liste. Query: status, lieferant_id, von, bis. Antwort: { items[], anzahl, stats } |
| POST | /chat/api/einkauf/avis | Neues Avis. Body: lieferant_id, datum, positionen[{artikel_bezeichnung, soll_menge, soll_einheit, soll_preis}] |
| GET | /chat/api/einkauf/lieferanten/avis-config | Lieferanten mit Avis-Feldern fuer Dropdown |
Einkauf – Lieferanten-Konfiguration
Seite /einkauf/lieferanten-config.html — Avis-Einstellungen und Artikel-Cross-Reference pro Lieferant. Accordion-Liste aller Lieferanten mit Inline-Konfiguration und Cross-Reference-Tabelle pro Lieferant.
Features: Stat-Kacheln (Gesamt/Aktiv/Verwogen/Cross-Refs) · Suche + Filter (Alle/Aktiv/Inaktiv) · Accordion-Details mit zwei Tabs (Konfiguration + Cross-Reference) · Quick-Toggle Avis aktiv/inaktiv direkt in der Listenzeile · Formular-Felder: avis_aktiv, gewichts_logik, toleranz_gewicht_prozent, toleranz_preis_prozent, referenz_dokumente · Expliziter Speichern-Button (kein Auto-Save) · Cross-Reference-Tabelle: Lieferant-Bezeichnung ↔ Interne Rohware ↔ Einheit ↔ Umrechnungsfaktor · Inline-Hinzufuegen neuer Cross-Refs · Loeschen mit Bestaetigung · RUDI Chat-Panel (Modul: einkauf) · escHtml XSS-Schutz · Toast-System
API-Pfade:
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/lieferanten/avis-config | Alle Lieferanten mit Avis-Feldern + cross_ref_count |
| PUT | /chat/api/einkauf/lieferanten/:id/avis-config | Avis-Konfiguration speichern. Body: avis_aktiv, gewichts_logik, toleranz_gewicht_prozent, toleranz_preis_prozent, referenz_dokumente |
| GET | /chat/api/einkauf/cross-reference/:lieferantId | Cross-Reference-Eintraege fuer einen Lieferanten |
| POST | /chat/api/einkauf/cross-reference | Neuen Eintrag anlegen. Body: lieferant_id, rohware_id, lieferant_bezeichnung, lieferant_einheit, umrechnungsfaktor |
| DELETE | /chat/api/einkauf/cross-reference/:id | Eintrag loeschen |
Chargen-Verwaltung
Seite /einkauf/chargen.html — Tages- und Wochenansicht der Rohwaren-Chargen. Tag-Navigation, collapsible Kategorie-Gruppen, klickbare Zellen zum Bearbeiten (Modal), Farbkodierung nach Herkunft (Lieferung / Manuell), Suche ueber API + lokales Highlight, Excel- und PDF-Export.
Features: Tag/Woche-Ansicht · Datum-Navigation (Vor/Zurueck/Heute) · Bis zu 10 Zaehlung-Spalten (dynamisch erweiterbar) · Edit-Modal mit Past-Date-Warnung · Statistik-Kacheln (Gesamt/Befuellt/Offen/Vollstaendigkeit) · RUDI Chat-Panel (Modul: einkauf) · Excel-Export (SheetJS, nach Kategorie gruppiert) · PDF-Export (jsPDF + AutoTable, A4 Quer)
API-Pfade (alle ueber /chat/api/einkauf/chargen/):
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/chargen/tag?datum=YYYY-MM-DD | Alle Rohwaren + Chargen-Eintraege fuer einen Tag |
| GET | /chat/api/einkauf/chargen/woche?start=YYYY-MM-DD | Wochenfortschritt (Mo-So): befuellt/gesamt pro Tag |
| GET | /chat/api/einkauf/chargen/suche?q=TERM | Volltext-Suche ueber Rohware und Chargennummern |
| GET | /chat/api/einkauf/chargen/statistik?datum=YYYY-MM-DD | Tagesstatistik: befuellt, gesamt |
| PUT | /chat/api/einkauf/chargen/:id/zelle | Zelle aktualisieren. Body: spalte, wert, origin |
| POST | /chat/api/einkauf/chargen/zelle | Neue Zelle erstellen. Body: datum, rohware_id, spalte, wert, origin |
| DELETE | /chat/api/einkauf/chargen/:id/zelle | Zelle loeschen. Body: spalte |
Bestand / Inventur
Seite /einkauf/bestand.html — Tages- und Wocheninventur der Rohwaren-Bestaende. Tag/Woche-Toggle, Suchfeld (Komma-getrennte Mehrfachsuche mit Gelb-Highlight), Vortagsvergleich (Auge-Button), Vortag kopieren, Tag loeschen mit 60s-Undo, Mehrfachzeilen pro Rohware, Kategorie-Export-Modal.
Rohware-Typen: 4 Typen — standard (Rohwaren in kg), bio (Bio-Rohwaren), packaging (Verpackungen in Stueck), supplies (Hilfsstoffe & Sonstiges: Bleche, Koerbe, Rollwagen, Aufguss, Behandlungsmittel, Saftbinder). Gruppierung nach Kategorie (BIO-Rohwaren, Fruechte, Gemuese, Kraeuter, Salat, Verpackung & Hilfsstoffe, Sonstiges).
Features: Tag/Woche-Ansicht · Suchfeld (Rohware oder Charge, komma-separiert) · Vortagsvergleich (Auge-Icon, Vortag-Werte in klein/grau) · Vortag kopieren (nur wenn Tag leer) · Tag loeschen + Undo (60s) · + Zusatzzeilen pro Rohware (x zum Loeschen) · Alle auf-/zuklappen-Button · Kategorie-Auswahl beim Excel/PDF-Export · Datum-Navigation · Inline-Edit (Enter/Blur/Escape) · Auto-Berechnung (colli × kg_pro_colli, lief_colli × lief_kg_pro_colli) · Unterdeckungs-Warnung (rot) · Statistik-Kacheln · Summenzeile · RUDI Chat-Panel (Modul: einkauf)
API-Pfade (alle ueber /chat/api/einkauf/bestand/):
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/bestand?datum=YYYY-MM-DD | Alle Rohwaren + Bestandszeilen fuer einen Tag |
| GET | /chat/api/einkauf/bestand/statistik?datum=YYYY-MM-DD | Tagesstatistik: erfasst, gesamt, bestand_kg |
| GET | /chat/api/einkauf/bestand/woche?start=YYYY-MM-DD | Wochendaten ab Montag: { start, tage: [{erfasst, gesamt}] } |
| POST | /chat/api/einkauf/bestand | Neue Zeile anlegen. Body: datum, rohware_id, feld-Werte |
| PUT | /chat/api/einkauf/bestand/:id/zelle | Zelle aktualisieren. Body: spalte, wert |
| DELETE | /chat/api/einkauf/bestand/:id | Einzelne Zeile loeschen |
| DELETE | /chat/api/einkauf/bestand/tag?datum=YYYY-MM-DD | Ganzen Tag loeschen. Gibt backup-Array zurueck. |
| POST | /chat/api/einkauf/bestand/kopieren | Vortag kopieren. Body: { quellDatum, zielDatum } |
| POST | /chat/api/einkauf/bestand/wiederherstellen | Geloeschten Tag wiederherstellen. Body: { eintraege } |
| POST | /chat/api/einkauf/bestand/zeile-hinzufuegen | Zusatzzeile fuer Rohware. Body: { datum, rohware_id } |
Einkauf – Kontrakte
Seite /einkauf/kontrakte.html — Verwaltung von Rahmenvertraegen mit Lieferanten. Stats-Kacheln (aktive Kontrakte, bald ablaufend, gesamt), sortierbare Tabelle mit Ablauf-Warnung (90 Tage), Glasmorphism-Modal zum Erstellen/Bearbeiten, Excel- und PDF-Export (A4 Quer).
Features: Filter nach Lieferant/Rohware/Suchtext/Nur-aktive · Ablauf-Badge (rot wenn < 90 Tage) · Abgelaufene Zeilen grau/durchgestrichen · Sortierung per Spalten-Header · RUDI Chat-Panel (Modul: einkauf) · Excel-Export (SheetJS) · PDF-Export (jsPDF + AutoTable, A4 Quer)
API-Pfade (alle ueber /chat/api/einkauf/):
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/kontrakte | Alle Kontrakte. Query: aktiv=1, suche=TEXT |
| GET | /chat/api/einkauf/kontrakte/faellig?tage=90 | Bald ablaufende Kontrakte |
| POST | /chat/api/einkauf/kontrakte | Neuer Kontrakt. Body: lieferant_id, rohware_id, datum_von, datum_bis, menge, intervall, preis, notizen, benachrichtigung_email |
| PATCH | /chat/api/einkauf/kontrakte/:id | Kontrakt aktualisieren. Body: beliebige Felder |
| DELETE | /chat/api/einkauf/kontrakte/:id | Kontrakt loeschen |
Einkauf – Preislisten
Seite /einkauf/preislisten.html — Verwaltung und KI-gestuetzte Extraktion von Lieferanten-Preislisten. Upload per Drag&Drop (xlsx, xls, csv, pdf), KI-Analyse mit Fortschrittsanzeige, Mapping unbekannter Artikel auf Rohwaren per Dropdown.
Features: Stat-Kacheln (Aktiv/Entwurf/Archiviert/Letzte Aktualisierung – klickbar, filternd) · Upload-Karte mit Drag&Drop-Zone, Lieferant-Dropdown, Gueltig-ab-Datum · Fortschrittsbalken waehrend KI-Extraktion · Portal-Scraper-Status (wenn Portal-Quellen vorhanden) · Sortierbare Tabelle (Lieferant, Datei, Quelle-Badge, Positionen, Status, Datum, Aenderungen) · Detail-Modal mit Positionstabelle und Preisvergleich (gruen=guenstiger, rot=teurer) · Ungemappte Artikel gelb markiert mit Zuordnungs-Dropdown · "Aktivieren" und "Loeschen" nur fuer Entwuerfe · RUDI Chat-Panel (Modul: einkauf)
API-Pfade (alle ueber /chat/api/einkauf/):
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/lieferanten | Lieferantenliste fuer Dropdown |
| GET | /chat/api/einkauf/preislisten | Liste. Query: status, lieferant_id, quelle |
| GET | /chat/api/einkauf/preislisten/:id | Detail mit Positionen-Array |
| POST | /chat/api/einkauf/preislisten/upload | Datei hochladen (multipart). Felder: datei, lieferant_id, gueltig_von, quelle |
| POST | /chat/api/einkauf/preislisten/:id/aktivieren | Preisliste aktivieren (Entwurf -> Aktiv, bisherige archivieren) |
| DELETE | /chat/api/einkauf/preislisten/:id | Preisliste loeschen (nur Entwuerfe) |
| POST | /chat/api/einkauf/preislisten/:id/positionen/:posId/mapping | Rohware zuordnen. Body: { rohware_id } |
| GET | /chat/api/einkauf/preise/scrape/status | Portal-Scraper-Status (laufend, fehler, zuletzt_lauf, naechster) |
| GET | /chat/api/einkauf/rohwaren | Rohwaren fuer Mapping-Dropdown |
Einkauf – Preisabweichungen
Seite /einkauf/preisabweichungen.html — Preisabweichungs-Dashboard: Uebersicht aller Abweichungen zwischen Soll- und Referenzpreis mit Ampel-Visualisierung (gruen/gelb/rot), Akzeptanz- und Reklamations-Workflow sowie Top-Lieferanten-Auswertung.
Features: 4 Stat-Kacheln (Offen, Rot/Dringend, Gelb/Pruefen, Offene Differenz EUR) als klickbare Filter · Filter-Bar: Lieferant, Datum von/bis, Status · Tabelle mit 10 Spalten, sortierbar, horizontales Scrollen auf Mobile · Ampel-Dot (gruen/gelb/rot) pro Zeile · Aktions-Buttons: Akzeptieren (nur offen), Reklamieren (nur offen), Notiz-Textarea pro Zeile · Batch-Button "Alle Bagatellen akzeptieren" · Top-Lieferanten-Karten mit Abweichungs-Balken · RUDI Chat-Panel (Modul: einkauf)
API-Pfade:
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /api/einkauf/preisabweichungen | Liste. Query: status, ampel, lieferant_id, datum_von, datum_bis |
| GET | /api/einkauf/preisabweichungen/dashboard | Kachel-Werte + top_lieferanten[] |
| PUT | /api/einkauf/preisabweichungen/:id | Aktion. Body: { aktion: "akzeptiert"|"reklamiert", notizen: "..." } |
| POST | /api/einkauf/preisabweichungen/bagatellen | Alle Bagatellen akzeptieren. Body: { lieferant_id? } |
| GET | /api/einkauf/lieferanten | Lieferantenliste fuer Dropdown |
Einkauf – Preisanalyse
Seite /einkauf/preisanalyse.html — Preisanalyse-Dashboard mit Trendverlauf, Lieferantenvergleich und auto-generierten Einsparhinweisen. Chart.js-Liniendiagramm mit Zeitraum-Wahl (3M/6M/12M), Dark-Mode-optimierten Farben und EUR-Tooltip-Format.
Features: 4 Stat-Kacheln (Aktive Lieferanten, Rohwaren mit Preisen, Aenderungen letzter Monat, Einsparpotenziale) · Rohware-Dropdown (GET /rohwaren) · Preisverlauf-Chart (Chart.js lokal, /shared/chart.umd.min.js) mit einer Linie je Lieferant · Zeitraum-Buttons 3M/6M/12M · Lieferantenvergleich-Tabelle: Rang, Lieferant, Preis, Avg 12M, Trend-Pfeil, vs-Bester · Hinweise-Grid (gruen/orange/rot-Karten) · Export-Button (xlsx-Download) · RUDI Chat-Panel (Modul: einkauf)
API-Pfade (alle ueber /chat/api/einkauf/):
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/analyse/stats | Kachel-Werte: lieferanten, rohwaren, aenderungen, einsparpotenziale |
| GET | /chat/api/einkauf/analyse/trend/:rohwareId | Preisverlauf. Query: monate=3|6|12. Antwort: { labels[], datasets[{label, data[]}] } |
| GET | /chat/api/einkauf/analyse/vergleich/:rohwareId | Lieferantenvergleich fuer Rohware. Antwort: [{lieferant_name, preis_aktuell, preis_avg_12m, trend_prozent}] |
| GET | /chat/api/einkauf/analyse/hinweise | Auto-generierte Hinweise. Antwort: [{titel, text, typ: gruen|orange|rot}] |
| GET | /chat/api/einkauf/analyse/export | Excel-Export. Query: rohware_id?, lieferant_id?. Datei: preisanalyse.xlsx |
| GET | /chat/api/einkauf/rohwaren | Rohwaren-Liste fuer Dropdown |
Einkauf – Bestellungen
Seite /einkauf/bestellungen.html — Kundenbestellungen erstellen und verwalten. Zwei Tabs: "Bestellung erstellen" (Einstellungen + Multi-Select-Artikel + Positionstabelle + Excel-Export) und "Bestellhistorie" (collapsible Cards, loeschbar).
Features: Bestelldatum (default: morgen) · Empfaenger + CC E-Mails · Multi-Select-Dropdown mit Suchfeld und Checkbox pro Rohware · Ausgewaehlte Artikel als Tags · Bestand-Daten (Bedarf/Einkauf) automatisch befuellt · Editierbare Mengen und Einheiten · Excel-Export (SheetJS, Dateiname Bestellung_DD-MM-YYYY.xlsx) · Bestellhistorie collapsible mit Loeschen-Button · RUDI Chat-Panel (Modul: einkauf)
API-Pfade (alle ueber /chat/api/einkauf/):
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/bestellungen | Liste aller Bestellungen mit positionen[] |
| GET | /chat/api/einkauf/bestellungen/:id | Einzelne Bestellung |
| POST | /chat/api/einkauf/bestellungen | Neue Bestellung. Body: bestelldatum, empfaenger_email, cc_emails[], notizen, positionen[{rohware_id, rohware_name, menge, einheit}] |
| DELETE | /chat/api/einkauf/bestellungen/:id | Bestellung loeschen. Antwort: {status: 'geloescht'} |
| GET | /chat/api/einkauf/rohwaren | Rohwaren-Liste fuer Artikel-Auswahl |
| GET | /chat/api/einkauf/bestand?datum=YYYY-MM-DD | Bestand fuer Bedarf/Einkauf-Vorbefuellung |
Einkauf – Stammdaten
Seite /einkauf/stammdaten.html — Verwaltung von Lieferanten, Rohwaren (Artikeln) und Kategorien. Drei Tabs, jeweils mit Suchfeld, Filtern, Tabelle und Glasmorphism-Modals zum Erstellen/Bearbeiten.
Features: Lieferanten (Name, E-Mail, Kontaktperson, Telefon, CRUD) · Rohwaren (Name, Kategorie, Typ: bio/standard/packaging/supplies, CRUD) · Typ-Badges (gruen=bio, cyan=standard, grau=packaging, braun=supplies) · Kategorien (CRUD, Loeschen mit Hinweis) · Kategorie-Dropdown synchronisiert zwischen Tab und Modal · Confirm-Dialog vor Loeschungen · Skeleton-Loader · RUDI Chat-Panel (Modul: einkauf)
API-Pfade (alle ueber /chat/api/einkauf/):
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/lieferanten | Alle Lieferanten |
| POST | /chat/api/einkauf/lieferanten | Neuer Lieferant. Body: name, email, kontakt, telefon |
| PUT | /chat/api/einkauf/lieferanten/:id | Lieferant aktualisieren |
| DELETE | /chat/api/einkauf/lieferanten/:id | Lieferant loeschen |
| GET | /chat/api/einkauf/rohwaren | Alle Rohwaren mit kategorie_id und typ |
| POST | /chat/api/einkauf/rohwaren | Neue Rohware. Body: name, kategorie_id, typ |
| PUT | /chat/api/einkauf/rohwaren/:id | Rohware aktualisieren |
| GET | /chat/api/einkauf/kategorien | Alle Kategorien |
| POST | /chat/api/einkauf/kategorien | Neue Kategorie. Body: name |
| PUT | /chat/api/einkauf/kategorien/:id | Kategorie umbenennen |
| DELETE | /chat/api/einkauf/kategorien/:id | Kategorie loeschen |
Vorgangsmodell – Phase 1 (Datenmodell & Migration)
Das zentrale Vorgangsmodell klamert alle Beschaffungsbelege (Bestellung → Avis → Wareneingang → Reklamation → Rechnung → Gutschrift) in einer einzigen vorgang-Tabelle. Phase 1 legt das Datenbankschema an und backfilled alle bestehenden Wareneingaenge (1770 Stk.), Reklamationen (144 Stk.) und Rechnungen.
Neue Tabellen in ~/einkauf/einkauf.db:
| Tabelle | Beschreibung |
|---|---|
vorgang | Zentrale Klammer. Status: angelegt|bestellt|avisiert|teilgeliefert|geliefert|geprueft|reklamiert|verrechnet|abgeschlossen|storniert |
vorgang_referenz | n:m Belege zu Vorgang (beleg_typ: bestellung|avis|lieferschein|wareneingang|rechnung|reklamation|gutschrift) |
bestellung | Bestellungen (Telefon/Mail/Portal/App) mit kanal, voicenote_pfad, erfasst_von |
bestellung_position | Positionen pro Bestellung (rohware_id, soll_menge, einheit, country_hint) |
lieferant_zertifikat | Bio/IFS/GLOBALG.A.P./QS-Zertifikate pro Lieferant mit Ablauf-Erinnerung |
Neue Spalten (ALTER TABLE, bestehende Daten unveraendert): wareneingaenge.vorgang_id, .herkunftsland_iso, .quality_status, .auto_validierung_json · we_positionen.soll_menge_quelle, .abweichung_kategorie · reklamationen.vorgang_id, .auto_erstellt, .ki_vorschlag_json, .freigabe_status · cockpit_auffaelligkeiten.vorgang_id, .claude_kommentar
View: vorgang_uebersicht — Joined-View mit Lieferant-Name und Beleg-Zaehler (WE/Reks/Rechnungen/Bestellungen).
DB-Layer:
| Datei | Funktionen |
|---|---|
~/rudi-chat/lib/edb/vorgang.js | createVorgang, getVorgang, listVorgaenge, updateStatus, updateRisiko, linkBeleg, getReferenzen, getVorgangByBeleg, closeVorgang, getRisikoStats, getVorgangsKette |
~/rudi-chat/lib/edb/bestellung.js | createBestellung, getBestellung, listBestellungen, copyLastBestellung, storniereBestellung |
Migration-Skripte:
| Skript | Funktion |
|---|---|
~/einkauf/migrations/001_vorgangsmodell.js | Migration ausfuehren (idempotent, 2x laufbar ohne Schaden) |
~/einkauf/migrations/001_vorgangsmodell_rollback.js | Rollback: neue Tabellen loeschen, neue Spalten nullen |
Backfill-Ergebnisse (2026-04-27): 1770 WE-Vorgaenge · 144 Reklamationen verlinkt · 25 Rechnungen an WE-Vorgaenge · 744 neue Rechnungs-Vorgaenge (verrechnet) · 0 WE ohne vorgang_id
Hinweis: Phase 1 legt das Datenmodell an. API-Routes fuer Bestellungen: Phase 2 (routes/bestellung.js). Feature-Flag vorgang_anzeige steuert Frontend-Sichtbarkeit.
Migration 002 – Backfill-Cleanup (2026-04-28, Korrektur 3 mib-logik-Audit)
Phase-1 hatte fuer jede Rechnung ohne eindeutigen WE-Match einen eigenen Vorgang angelegt. Ergebnis: 746 "Rechnung-ohne-WE"-Vorgaenge (30% Datenmüll). Migration 002 bereinigt das idempotent in 3 Stufen:
- Stufe A: Match-Versuch (strikt via lieferschein_nr/chargennummer + loose via +/-14 Tage). 2 Merges gefunden, 677 uneindeutig (zu viele Lieferanten-WEs im Fenster), 65 ohne Treffer.
- Stufe B: Status-Markierung:
status='nur_rechnung'(65) undstatus='nur_rechnung_uneindeutig'(677). Neue Spaltevorgang.notizfuer Match-Hinweise. - Stufe C: View
vorgang_uebersichtneu — filtertnur_rechnung*heraus, zeigt nur operative Vorgaenge (1771). Neue Spaltekategorie(vollstaendig|nur_we|nur_rechnung|nur_rechnung_uneindeutig|leer). Separate Viewvorgang_uebersicht_nur_rechnungfuer die 742 verbleibenden.
| Skript | Funktion |
|---|---|
~/einkauf/migrations/002_vorgang_cleanup.js | Cleanup ausfuehren (idempotent). Backups: 002_backup_*.json. Bericht: 002_cleanup_report.json. |
~/einkauf/migrations/002_vorgang_cleanup_rollback.js | Rollback: stellt geloeschte Vorgaenge + Referenzen aus Backup-JSON wieder her |
Ergebnis (2026-04-28): 2516 → 2513 Vorgaenge · Operational: 1771 · Nur-Rechnung: 742 (aus Listen rausgefiltert) · 1 Leervorgang geloescht
Vorgangsmodell – Phase 2: Bestellungs-Erfassung
Backend-Route ~/rudi-chat/routes/bestellung.js, gemountet als /chat/api/bestellung. Alle Endpunkte benoetigen requireAuth + requireModule('einkauf'). Schreib-Endpunkte zusaetzlich requireWrite + requireCsrf. Audit-Log bei jeder Mutation (modul='bestellung').
Feature-Flag: bestellung_voice (Default: OFF) — Voice-Endpoint gibt 403 wenn deaktiviert.
| Methode | Route | Auth | Beschreibung |
|---|---|---|---|
| GET | /chat/api/bestellung | Auth+Modul | Liste. Filter: ?lieferant_id=&status=&kanal=&von=&bis=&limit=50&offset=0 |
| GET | /chat/api/bestellung/:id | Auth+Modul | Einzelne Bestellung mit Positionen + verlinktem Vorgang |
| POST | /chat/api/bestellung | Auth+Write+CSRF | Neue Bestellung anlegen. Body: {lieferant_id, datum, kanal, bemerkung_freitext, positionen:[{artikel_text, soll_menge, einheit, country_hint}]}. Legt automatisch Vorgang an (status='bestellt'). Response: {bestellung_id, vorgang_id} |
| PUT | /chat/api/bestellung/:id | Auth+Write+CSRF | Felder aendern (nur wenn status='aktiv'): kanal, bemerkung_freitext, datum |
| DELETE | /chat/api/bestellung/:id | Auth+Write+CSRF | Stornieren (kein hard delete). Setzt Bestellung + verlinkten Vorgang auf status='storniert' |
| POST | /chat/api/bestellung/copy-last | Auth+Modul+CSRF | Positionen der letzten Bestellung eines Lieferanten laden. Body: {lieferant_id}. Response: {kopiert_von, positionen} |
| GET | /chat/api/bestellung/lieferant/:id/template | Auth+Modul | Standardkorb: haeufigste Positionen der letzten 30 Tage. Query: ?tage=30 |
| POST | /chat/api/bestellung/:id/voice | Auth+Write+CSRF | Voice-Notiz (multipart audio). Transkription via Gemini STT + Claude Positions-Extraktion. Nur wenn Feature-Flag bestellung_voice aktiv (sonst 403). Response: {transcription, vorgeschlagene_positionen} |
Claude-Tools (Chat):
| Tool | Beschreibung |
|---|---|
bestellung_erfassen | Erfasst eine neue Bestellung im Chat. Input: lieferant_name (fuzzy), datum, kanal, positionen[]. Legt Vorgang an und bestaetigt mit ID. |
bestellung_kopieren | Zeigt letzte Bestellung eines Lieferanten als Vorlage. Input: lieferant_name. Gibt Positionen zur Pruefung aus. |
Handler-Dateien: ~/rudi-chat/routes/bestellung.js · ~/rudi-chat/lib/tools/handlers/bestellung.js · multer-secure.js um Audio-Preset erweitert (wav/mp3/m4a/webm/ogg)
Multer Audio-Preset: max 25 MB, Magic-Bytes-Check (WAV/MP3/OGG/WebM/M4A), kein EXIF-Strip (Audio hat kein EXIF). Destination: ~/uploads/voice-bestellung/
Frontend Bestellungs-Erfassung (Phase 2 UI)
Ziel: Telefonbestellungen in <30 Sekunden erfassen. Mobile-first, 375px-tauglich, Touch-Targets ≥36px, Apple Glasmorphism.
| Seite | Pfad | Beschreibung |
|---|---|---|
| Listen-Seite | /einkauf/bestellung/ | Tabelle aller Bestellungen mit Filtern (Lieferant, Datum, Status, Suche). Paginiert (50/Seite). Klick auf Zeile → Detail. "+ Neue Bestellung" oben rechts. |
| Neu-Seite (Quickform) | /einkauf/bestellung/neu.html | 4-Schritt-Wizard: (1) Lieferant-Autocomplete → (2) Modus (Letzte kopieren / Standardkorb / Leer / Voice wenn Flag aktiv) → (3) Positionen-Editor → (4) Bemerkung + Speichern. Stoppuhr-KPI in Nav-Bar sichtbar. |
| Detail-Seite | /einkauf/bestellung/detail.html?id=X | Bestellungs-Kopf + Positionen-Tabelle + Vorgang-ID + Aktionen (Bearbeiten, Stornieren mit Modal). Voice-Bereich nur wenn Feature-Flag bestellung_voice aktiv. |
Feature-Flag bestellung_voice (Default OFF): Wenn aus → Voice-Modus-Card in Schritt 2 versteckt, Voice-Sektion in Detail-Seite ausgeblendet. Schaltbar in /admin/feature-flags.
Kachel in Einkauf-Dashboard: "Bestellung erfassen" (/einkauf/index.html) verlinkt direkt auf /einkauf/bestellung/neu.html (hervorgehoben in Accent-Farbe).
Dateien: /var/www/html/einkauf/bestellung/ (index.html, index.js, neu.html, neu.js, detail.html, detail.js, bestellung.css)
Produktionsplanung
Rohwaren-Bedarfsberechnung aus OData-Sync + Stücklisten. Datenbank: ~/produktionsplanung/produktionsplanung.db.
| Methode | Route | Beschreibung |
|---|---|---|
| POST | /chat/api/produktionsplanung/upload | Excel-Tagesbedarf hochladen. Feld: datei. |
| POST | /chat/api/produktionsplanung/stuecklisten/import | Stücklisten-Excel importieren. Feld: datei. |
| GET | /chat/api/produktionsplanung/stuecklisten/status | Stücklisten-Status: Anzahl Zeilen, Artikel, letzter Import. |
| GET | /chat/api/produktionsplanung/tage | Verfuegbare Tage mit importierten Daten. |
| GET | /chat/api/produktionsplanung/ergebnis/:datum | Berechnetes Ergebnis (Rohwaren + Unmatched) fuer ein Datum. |
| GET | /chat/api/produktionsplanung/detail/:datum/:rw_id | Detail-Aufschlüsselung einer Rohware fuer ein Datum. |
| GET | /chat/api/produktionsplanung/unmatched/:datum | Nicht zugeordnete Artikel fuer ein Datum. |
| POST | /chat/api/produktionsplanung/odata/sync | Manueller OData-Sync. Body: {datum} (opt, Default heute). |
| GET | /chat/api/produktionsplanung/odata/status | Sync-Status: aktiv, letzter Sync, Credentials vorhanden. |
Prognose-Endpunkte
KI-gestuetztes Lernmodell (EWMA) fuer 14-Tage-Rohwaren-Prognose. Externe Faktoren: Wetter (Open-Meteo, Freiburg), Schulferien + Feiertage BW. Modell-Faktoren werden nach jedem OData-Sync automatisch aktualisiert.
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/produktionsplanung/prognose/rohwaren | Alle Rohwaren mit Historik-Länge und MAPE. |
| GET | /chat/api/produktionsplanung/prognose/historik/:rohware_id | Historische Ist-Werte + aktuelle 14-Tage-Prognose. Query: ?tage=365. |
| POST | /chat/api/produktionsplanung/prognose/berechnen/:rohware_id | Prognose neu berechnen und in DB speichern. Response: {prognosen, mape, warnung}. |
| GET | /chat/api/produktionsplanung/prognose/vergleich/:rohware_id | Prognose vs. Ist (rueckwirkend). Query: ?von=&bis= (Default: letzte 90 Tage). Response: {vergleich, mape}. |
| GET | /chat/api/produktionsplanung/prognose/externe-faktoren | Wetter + Ferien fuer die naechsten 14 Tage. |
| POST | /chat/api/produktionsplanung/prognose/upload | Excel-Upload fuer historische Daten. Feld: file. |
| POST | /chat/api/produktionsplanung/prognose/ausreisser/:datum/:rohware_id | Ausreisser ein-/ausschalten. Body: {ausgeschlossen: true|false}. |
| GET | /chat/api/produktionsplanung/prognose/lernfortschritt/:rohware_id | Modell-Faktoren, MAPE-Verlauf (woechentlich) und KI-Erklaerungen. |
System
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/system/status | Server-Status: CPU, RAM, Disk, Services, Uptime, OS-Info |
Feature-Flag-System
Zentrale Laufzeit-Schalter fuer RUDI-Features. Kein Code-Aenderung, kein Service-Restart noetig. DB: ~/feature-flags/flags.db (eigene SQLite, WAL-Mode). Cache-Reload alle 30 Sekunden. Jede Aenderung wird in flags_history auditiert.
Aktuelle Flags (Phase-0-Matrix)
| Flag | Default | Wirkung wenn OFF |
|---|---|---|
vorgang_anzeige | OFF | Frontend zeigt nur alten Wareneingang |
bestellung_voice | OFF | Voice-Bestellung versteckt, nur Quickform |
we_country_pflicht | ON | Country-of-Origin wird optional (FSMA-Risiko!) |
we_vision_warnung | ON | Vision-Hinweise im WE-Modal versteckt |
auto_reklamation_solvega | ON (Schatten) | Reklamations-Vorschlaege nicht generiert |
auto_reklamation_versand | OFF | Vorschlaege ja, kein Auto-Mail-Versand |
pipeline_vision_cross | ON | Pipeline laeuft nur mit Tesseract |
bolt_sync_active | ON | Bolt.new-Datenpull pausiert (Kill-Switch) |
recall_drill_cron | ON | Woechentlicher FSMA-Recall-Drill deaktiviert |
vision_backfill_nightly | ON | Vision-Backfill-Cron aktiv (02:45 UTC, 500 Bilder/Nacht, wareneingang_bilder + reklamation_bilder) |
claude_briefing_pwa | ON | Auffaelligkeiten nicht in PWA-Briefing gepusht |
upload_hardening | ON | Legacy-Multer (50 MB, kein EXIF-Strip, kein Magic-Bytes-Check) |
bio_quality_gate | ON | BIO-WE mit Vision-Mangel wird NICHT gesperrt — nur Warnung (IFS-Risiko! Nur fuer Tests deaktivieren) |
API-Endpunkte (Feature Flags)
| Methode | Route | Auth | Beschreibung |
|---|---|---|---|
| GET | /chat/api/auth/flags | requireAuth | Alle Flags als Name->Boolean-Map (scope-aware, fuer Frontend-Loader) |
| GET | /chat/api/admin/flags | requireAdmin | Alle Flags mit History-Anzahl (Admin-UI) |
| GET | /chat/api/admin/flags/:name | requireAdmin | Ein Flag |
| PUT | /chat/api/admin/flags/:name | requireAdmin + CSRF | Flag setzen. Body: {aktiv: bool, grund: string}. Schreibt Audit-Eintrag (modul: flags, aktion: flag_change). |
| GET | /chat/api/admin/flags/:name/history | requireAdmin | Letzte 50 Aenderungen |
Zentrales Audit-Log (Phase 0)
FSMA-204 / EU-Lebensmittelrueckverfolgung konformes Audit-Log. Eigenstaendige SQLite-DB ~/audit/audit.db (WAL, append-only via SQL-Trigger). Jede Datenänderung an Vorgangs-relevanten Daten wird unveraenderlich geloggt.
Backend: ~/rudi-chat/lib/audit.js | Route: ~/rudi-chat/routes/admin-audit.js | Mount: /chat/api/admin/audit
Append-only: SQL-Trigger blockieren UPDATE + DELETE auf der log-Tabelle (SQLite RAISE ABORT). Cloud-Backup: ~/bin/cloud-sync.sh databases (alle 2h direkt aus ~/audit/audit.db).
| Methode | Route | Auth | Beschreibung |
|---|---|---|---|
| GET | /chat/api/admin/audit | requireAdmin | Paginierte Abfrage. Query-Params: ressource_typ, ressource_id, user_id, modul, aktion, ts_from, ts_to, limit, offset |
| GET | /chat/api/admin/audit/stats | requireAdmin | Statistiken: Eintraege heute/Woche/Monat, Top-User, Top-Module, Top-Aktionen |
| GET | /chat/api/admin/audit/ressource/:typ/:id | requireAdmin | Lebenslauf einer Ressource (chronologisch, fuer FSMA-Recall) |
Bolt-Migration-Dashboard (Phase 6 Vorgangsmodell)
Backend: ~/rudi-chat/routes/admin-bolt.js | Mount: /chat/api/admin/bolt-diff | Frontend: /admin/bolt-migration.html
Taeglicher Drift-Report zwischen bolt.new (Firebase) und RUDI fuer die drei Hauptkacheln: Bestand, Wareneingang, Reklamation. 4-Wochen-Parallelbetrieb mit Empfehlung fuer Umschaltung.
| Methode | Endpunkt | Auth | Beschreibung |
|---|---|---|---|
| GET | /chat/api/admin/bolt-diff/latest | requireAdmin | Letzter Diff-Bericht aus ~/backups/bolt-diff/ |
| GET | /chat/api/admin/bolt-diff/trend?days=7 | requireAdmin | Trend-Daten (max 30 Tage). Gibt Drift-Zeitreihe + Zaehler aller-Kacheln-unter-Schwelle. |
Cron: /etc/cron.d/bolt-diff-report — taeglich 03:00 UTC. Skript: ~/bin/bolt-diff-report.js. Output: ~/backups/bolt-diff/YYYY-MM-DD.json. Audit-Eintrag: modul=bolt-migration, aktion=diff_report.
Schwelle: 0.5% Drift je Kachel. Empfehlung BOLT_READONLY_OK wenn 7 Tage am Stueck alle Kacheln darunter. "Bolt auf Read-Only"-Button in Frontend setzt Feature-Flag bolt_sync_active=OFF (nur manuell, nie automatisch).
workflow-audit.js prueft taeglich ob letzter Bericht juenger als 36h ist und ob Drift-Schwelle ueberschritten.
Vorgangsmodell – Phase 7: Compliance & Claude-Briefing-Layer (2026-04-28)
FSMA-204-Compliance-Automatisierung + Lieferanten-Zertifikat-Management + vorgang_analyse-Tool fuer RUDI-Chat.
1. Recall-Drill aktiviert
Cron /etc/cron.d/recall-drill ist seit 2026-04-28 aktiv (Mo 06:00 UTC, vorher auskommentiert). Feature-Flag recall_drill_cron auf ON gesetzt. Skript: ~/bin/recall-drill.js. Log: ~/backups/recall-drill.log. CLI: --random | --charge <nr> | --we-id <id> | --json.
2. Lieferanten-Zertifikate
Frontend: /einkauf/zertifikate/index.html — Tabelle aller Zertifikate, Filter (alle/ablaufend/abgelaufen), + Neu / Edit-Modal / Loeschen. Rollen: requireAuth + requireModule('einkauf').
Cron: /etc/cron.d/zertifikat-erinnerung — taeglich 05:00 UTC. Skript: ~/bin/zertifikat-erinnerung.js. Prueft lieferant_zertifikat mit erinnerung_aktiv=1. Legt Cockpit-Eintraege typ='zertifikat_ablauf' an (warn = ablaufend, kritisch = abgelaufen). Duplikat-Schutz per UNIQUE-Check. Log: ~/backups/zertifikat-erinnerung.log.
| Methode | Route | Beschreibung |
|---|---|---|
| GET | /chat/api/einkauf/zertifikate | Liste. Query: lieferant_id, filter (alle|ablaufend|abgelaufen). Antwort: { zertifikate[], total }. Felder: id, lieferant_id, lieferant_name, typ, nummer, ausgestellt_am, gueltig_bis, status_berechnet. Auth: requireAuth + requireModule('einkauf'). |
| POST | /chat/api/einkauf/zertifikate | Neues Zertifikat anlegen. Body: lieferant_id*, typ*, nummer, ausgestellt_am, gueltig_bis, beleg_pfad, ausgestellt_von, erinnerung_aktiv, erinnerung_tage_vorher. Auth: requireWrite + requireCsrf + requireModule('einkauf'). |
| PUT | /chat/api/einkauf/zertifikate/:id | Zertifikat aktualisieren. Body: alle Felder optional (COALESCE-Update). Auth: requireWrite + requireCsrf + requireModule('einkauf'). |
| DELETE | /chat/api/einkauf/zertifikate/:id | Zertifikat loeschen. Auth: requireWrite + requireCsrf + requireModule('einkauf'). |
3. Tool vorgang_analyse
Neues RUDI-Chat-Tool (definitions.js + handlers/vorgang.js). Eingabe: vorgang_id ODER charge ODER we_id. Ausgabe: strukturierter Text mit Stammdaten, Beleg-Kette, Mengenvergleich, Reklamationen, Bilder/Vision, Lieferanten-Risiko-Score, Vollstaendigkeits-Score (0-1), FSMA-4h-Bewertung.
4. Briefing-Erweiterung (Phase 7)
briefing.js gibt jetzt compliance: { recall_drill_letzte, bolt_diff_status, zertifikate_ablaufend } zurueck. formatComplianceText() formatiert als lesbaren Text fuer Voice/Chat. shortSummary() erwaehnt ablaufende Zertifikate. Neue Exports: getRecallDrillLetzteErgebnisse(n), getBoltDiffStatus(), getZertifikateAblaufend(tage).
5. workflow-audit.js — checkZertifikate()
Neuer Check: prueft abgelaufene Zertifikate (→ kritisch) und in 14 Tagen ablaufende (→ warn). Laeuft im taegl. Workflow-Audit-Cron (04:00 UTC).
Backend-API (lib/audit.js)
| Funktion | Beschreibung |
|---|---|
write(entry) | Synchroner Audit-Eintrag <2ms (better-sqlite3, prepared stmt). entry: {user, modul, aktion, ressource_typ, ressource_id, before, after, req?, notiz?, opts?} |
writeAsync(entry) | Non-blocking via setImmediate (fuer hot paths) |
query(opts) | Paginierte Abfrage mit Filtern (ressource_typ, user_id, modul, aktion, ts_from, ts_to, limit, offset) |
getRecent(limit) | Letzte N Eintraege fuer Admin-UI |
getForRessource(typ, id) | Lebenslauf einer Ressource (chronologisch, Recall-faehig) |
getStats() | Zaehler heute/Woche/Monat + Top-User/Module/Aktionen |
middleware(modul) | Express-Middleware-Factory: loggt HTTP-Requests nach Response (non-blocking) |
Sensible Felder (password, password_hash, pin, api_key, token, secret etc.) werden vor dem Speichern automatisch durch [REDACTED] ersetzt. before/after-Felder auf max. 50 KB begrenzt (Truncation-Hinweis bei Ueberschreitung).
Backend-Modul (lib/feature-flags.js)
| Funktion | Beschreibung |
|---|---|
init() | DB oeffnen, Schema, Default-Flags seeden, Cache laden, 30s-Reload starten |
getFlag(name, default) | Synchron aus Cache (boolean). Fuer Backend-Checks. |
getFlagsForUser(user) | Map aller Flags, scope-aware (global / rolle:X / user:UUID) |
setFlag(name, aktiv, von, grund) | Schreibt + History-Eintrag + Cache sofort neu laden |
seedFlags(array) | Idempotent: legt Flags an ohne bestehende aktiv-Werte zu ueberschreiben |
Phase-0-Sicherheitsbausteine
Drei Sicherheitsmodule, die als Fundament fuer DSGVO-konforme Uploads und HMAC-gesicherte Webhook-Integrationen dienen. Hinzugefuegt 2026-04-27.
EXIF-Stripper (lib/exif-strip.js)
Entfernt EXIF-Metadaten (GPS, Kamera-Daten, Timestamps) aus Bild-Uploads. Verhindert DSGVO-Risiko bei Reklamations-/Wareneingangs-Fotos mit Mitarbeiter-Bezug (Geo-Koordinaten). Nutzt sharp().rotate() ohne withMetadata() — atomarer Datei-Tausch via tmp-Datei.
| Funktion | Beschreibung |
|---|---|
stripFile(srcPath, dstPath?) | Entfernt EXIF in-place (oder nach dstPath). Bei Fehler: ok:false, Original unveraendert. |
stripBuffer(buf, hint?) | Verarbeitet Buffer direkt. Bei HEIC/HEIF: Konvertierung zu JPEG. |
needsStripping(filePath) | Prueft ob Dateiformat EXIF enthalten kann (JPEG, PNG, WebP, HEIC, HEIF, AVIF, TIFF). |
Gehaerteter Multer-Helper (lib/multer-secure.js)
Factory fuer gehaertete Multer-Instanzen. Ersetzt direkte multer()-Aufrufe in Routen. Integriert: Mime-Whitelist, Magic-Bytes-Check (defense-in-depth gegen MIME-Spoofing), EXIF-Stripping, File-Size-Limit 25 MB. Feature-Flag upload_hardening schaltet gehaertete Pipeline ein (ON = Default) oder zurueck auf Legacy.
Mime-Presets: 'image' (JPEG/PNG/WebP/HEIC/HEIF), 'document' (PDF + Bilder), 'mixed' (alle). Magic-Bytes werden aus den ersten 12 Bytes der Datei gelesen — keine externe NPM-Abhaengigkeit.
| API | Beschreibung |
|---|---|
createMulter({destination, maxSize, maxFiles, accept, stripExif, filename}) | Gibt Multer-kompatibles Objekt mit .single(), .array(), .fields(), .any() zurueck. |
detectMagicType(filePath) | Liest erste 12 Bytes, gibt 'jpeg' | 'png' | 'webp' | 'heic' | 'pdf' | null zurueck. |
Aktuell genutzt: routes/einkauf.js — Wareneingang-Bild-Upload (WE-Fotos + Lieferschein-Scans).
HMAC-Middleware (lib/hmac-middleware.js)
Signaturpruefung fuer kuenftige Webhook-Endpunkte von Lieferanten-Portalen (Push-Avis). Kein Session-Cookie, kein CSRF. Auth via HMAC-SHA256 ueber timestamp + '\n' + rawBody. Clock-Skew-Pruefung (default 5 Min) verhindert Replay-Angriffe. crypto.timingSafeEqual verhindert Timing-Angriffe. Secrets werden nie geloggt.
Mount-Reihenfolge: Webhook-Router MUSS vor express.json() gemountet werden (raw body muss unverbraucht sein). In server.js am Anfang, vor globalem Body-Parser.
| Export | Beschreibung |
|---|---|
captureRawBody | Middleware: liest Stream, setzt req.rawBody (Buffer) und req.body (JSON-Objekt). |
hmacAuth({secret, header, algorithm, format, maxClockSkewSeconds}) | Factory: gibt Auth-Middleware zurueck. secret: 'env:NAME' | 'literal:...' | (req)=>string. |
Test-Endpunkt: POST /chat/api/hooks/test — HMAC-Secret: 'test-shared-secret'. Fuer Produktion: env:WEBHOOK_SECRET_LIEFERANTNAME in /etc/environment.
Webhook-Route-Gruppe (routes/hooks-example.js)
Gemountet als /api/hooks/* VOR globalem Auth. Neue Lieferanten-Webhooks werden hier als zusaetzliche router.post()-Eintraege angelegt.
| Methode | Route | Auth | Beschreibung |
|---|---|---|---|
| POST | /chat/api/hooks/test | HMAC (literal:test-shared-secret) | Test/Entwicklungs-Endpunkt. Antwortet mit ok:true + empfangenen Daten. |
Test-Suite & Self-Improvement
RUDI hat ein automatisches Test- und Lernsystem. Jeder gemeldete Bug fuehrt zu einem Fix, einem neuen Test und einer gelernten Regel — damit der gleiche Fehler nie wieder auftritt.
Master-Testrunner
| Befehl | Beschreibung |
|---|---|
node ~/bin/rudi-test.js | Alle Tests (Layout + API + Custom) |
node ~/bin/rudi-test.js --layout | Nur Layout-Tests (15 Seiten via Puppeteer) |
node ~/bin/rudi-test.js --api | Nur API-Endpunkte (14 Endpoints) |
node ~/bin/rudi-test.js --custom | Nur Custom-Checks (test-checks.json) |
node ~/bin/rudi-test.js --verbose | Ausfuehrliche Ausgabe |
Ergebnis: ~/rudi-chat/test-results.json (JSON), Exit-Code 0 = bestanden, 1 = Fehler.
Layout-Tests (15 Seiten)
Getestete Seiten: Dashboard, QMS, Aufgaben, Reklamation, Dateien, System, Pipeline, Maschinen, Maschine-Detail, Vorschlaege, Vorschlag-Detail, Notfall, Notfall-Druck, Doku, Chat.
Checks pro Seite:
- Layout: Overflow, Text-Truncation, Navigation, versteckte Panels
- Fehler: JS-Fehler, Resource-404s
- Bilder: Alle sichtbaren
<img>geladen (naturalWidth > 0) - Buttons: Korrekte Groesse (min 20×20px)
- Eingabefelder: Korrekte Groesse (min 50px breit, 20px hoch)
- API-Daten: Seiten mit Daten rendern mindestens 1 Datensatz
- Seitenspezifisch: Formulare, Thumbnails, Tabs, Galerien etc.
- Custom-Checks: Aus
~/rudi-chat/test-checks.json
Screenshots: ~/layout-tests/
/bugfix Skill — Self-Improvement-Loop
Der /bugfix Skill ist der Kern des Lernsystems. Er wird automatisch aktiviert wenn der User ein Problem beschreibt:
- „funktioniert nicht“, „ist kaputt“, „wird nicht angezeigt“
- „hier ist ein Fehler“, „das stimmt nicht“
- „habe etwas entdeckt was nicht korrekt funktioniert“
- „Bild laedt nicht“, „Button geht nicht“, „Seite zeigt nichts an“
- Oder jede andere Beschreibung eines Fehlverhaltens
Der Skill fuehrt automatisch 5 Schritte durch:
- Analyse: Betroffene Datei lesen, Root-Cause finden
- Fix: Minimaler, gezielter Fix implementieren
- Test: Neuen Check in
test-checks.jsonhinzufuegen (Regressions-Test) - Memory: Feedback-Datei schreiben (alle Agents lernen daraus)
- Verifikation:
node ~/bin/rudi-test.jsausfuehren
Deploy-Gate
Der /deploy Skill fuehrt vor jedem Deployment node ~/bin/rudi-test.js aus. Bei Fehlern wird das Deployment gestoppt.
Skills & Agents
| Typ | Name | Beschreibung |
|---|---|---|
| Skill | /bugfix | Bug fixen + Test + Memory (Self-Improvement) |
| Skill | /test | Tests manuell starten |
| Skill | /deploy | Deployment mit Pflicht-Test-Gate |
| Skill | /new-module | Neues RUDI-Modul erstellen |
| Skill | /qms-management | QMS-Verwaltung (IFS 2025) |
| Skill | /energie | PV, Speicher, BHKW |
| Skill | /mib-audit | MIB-Team starten (4 parallele Sicherheits-Agents) |
| Skill | /system-audit | Einzelner System-Audit (6 Bereiche, Score) |
| Agent | tester | QA — Layout-Tests, API-Tests, Bug-Registrierung (Haiku) |
| Agent | frontend-dev | HTML/CSS/JS mit Apple Glasmorphism (Sonnet) |
| Agent | backend-dev | Node.js/Express API-Routen (Sonnet) |
| Agent | chat-integrator | Claude-Tools registrieren (Sonnet) |
| Agent | qms-specialist | IFS 2025, Dokumente, Gap-Analyse (Sonnet) |
| Agent | pipeline-optimizer | Dokumenten-Pipeline QA (Sonnet) |
| MIB | mib-security | Security-Audit: Auth, CSRF, CSP, Firewall (Opus) |
| MIB | mib-backend | Backend-Audit: Tools, Routes, Daten (Sonnet) |
| MIB | mib-frontend | Frontend-Audit: Chat, CDN, Auth-Guard (Sonnet) |
| MIB | mib-doku | Doku-Audit: Memory, Rules, Agents (Haiku) |
MIB-Team (Men in Black)
Automatisiertes Sicherheits- und Qualitaets-Audit durch 4 parallele Spezialisten-Agents.
| Agent | Modell | Pruefbereich |
|---|---|---|
| mib-security | Opus | API-Keys, Auth, CSRF, CSP, Path-Traversal, Uploads, Nginx, Firewall |
| mib-backend | Sonnet | Tool-Handler, Route-Konsistenz, Datenintegritaet, Server-Stabilitaet |
| mib-frontend | Sonnet | Chat-Panel, CDN-Violations, Auth-Guard, Viewport, Script-Reihenfolge |
| mib-doku | Haiku | Memory-Links, Telegram-Reste, Agent-Definitionen, Rules, Doku |
Manuell starten: Im Chat sagen: Lasse die Men in Black ausruecken oder /mib-audit
Automatisch: Jeden Sonntag um 03:00 UTC via Cron-Job (~/bin/mib-audit.sh)
Berichte: ~/rudi-chat/audit-log.json (Score-Historie mit Trend)
Score-Berechnung: Security × 0.35 + Backend × 0.25 + Frontend × 0.20 + Doku × 0.20
| Score | Status | Aktion |
|---|---|---|
| 9–10 | Gruen | Kein Handlungsbedarf |
| 7–8 | Gelb | Verbesserungen empfohlen |
| 5–6 | Orange | Prioritaer beheben |
| < 5 | Rot | Sofort handeln |
Hintergrund-Jobs (Cron)
| Zeit (UTC) | Skript | Beschreibung |
|---|---|---|
| Mo 06:00 (AKTIV seit 2026-04-28) | ~/bin/recall-drill.js | FSMA-204-Compliance-Recall-Drill: zufaellige Charge, Rueckverfolgung 1-Schritt-vor+zurueck, Score ≥ 0.70 = bestanden. Feature-Flag recall_drill_cron ON. Log: ~/backups/recall-drill.log. Cron: /etc/cron.d/recall-drill. CLI: --random | --charge <nr> | --we-id <id> | --json. Phase 7 aktiviert. |
| 05:00 taeg. | ~/bin/zertifikat-erinnerung.js | Lieferanten-Zertifikat-Ablauf-Erinnerung: prueft lieferant_zertifikat mit erinnerung_aktiv=1, legt Cockpit-Eintraege typ='zertifikat_ablauf' an. Log: ~/backups/zertifikat-erinnerung.log. Cron: /etc/cron.d/zertifikat-erinnerung. Phase 7. |
| 02:45 taeg. | ~/bin/vision-backfill.js | Vision-Backfill: 500 Bilder/Nacht aus wareneingang_bilder + reklamation_bilder, Tagesbudget 5 EUR Hardstop. Feature-Flag: vision_backfill_nightly. Log: ~/backups/vision-backfill.log. Cron: /etc/cron.d/vision-backfill. |
| So 03:00 | ~/bin/mib-audit.sh | MIB-Security-Audit (4 Agents, Score-Bericht) |
| 06:15 taeg. | ~/bin/rudi-test.js | Master-Testrunner (API + Layout + Custom-Checks) |
| 04:30/05:30 | ~/bin/briefing-benjamin.js | Tages-Briefing Mein RUDI PWA |
| jede Min. | ~/bin/routines-runner.js | Mein-RUDI-Routinen-Runner |
| 03:30 taeg. | ~/bin/memory-hygiene.js | Memory-Hygiene Mein RUDI |
| 06:00 taeg. | ~/bin/bestand-alert.js | Bestand-Alert (E-Mail bei Unterschreitung) |
| Mo-Fr 08:00 | ~/bin/rek-erinnerung.js | Reklamations-Erinnerung (offene Faelle) |
| Min 23 stl. | ~/bin/lern-ruecklauf.js | HFX360-Lern-Ruecklauf |
| 03:45 taeg. | ~/bin/hfx360-stockitems-sync.js | HFX360 Stockitems-Sync |
| 05:30 taeg. | ~/bin/lern-frageliste.js | HFX360 Lern-Frageliste |
| 5 Min. | ~/bin/healthcheck-ping.sh | Health-Ping (Resilience) |
| 5 Min. | ~/bin/mcp-whitelist-update.sh | MCP-Whitelist-Update |
| 15 Min. | ~/bin/cleanup-chrome.sh | Chrome-Prozess-Cleanup |
| 2-stl. | ~/bin/cloud-sync.sh | Cloud-Sync DBs + Dateien (Resilience) |
| 01:00 taeg. | ~/bin/backup-config.sh | Config-Backup |
| 04:00 taeg. | ~/bin/disk-cleanup.sh | Temp-Cleanup + Disk-Cleanup |
| 05:30 taeg. | ~/bin/threat-intel.js | Threat-Intel-Check |
| 03:00 taeg. | ~/bin/email-backup.js | E-Mail-Backup (rudi@ + qms@, Delta-Query) |
| So 21+22 UTC | ~/bin/weekly-meta-run.js | Woechentlicher Meta-Run Mein RUDI |
Wichtige Dateien (Testing)
| Datei | Beschreibung |
|---|---|
~/bin/layout-test.js | Layout- & Funktions-Tests (Puppeteer, 15 Seiten) |
~/bin/rudi-test.js | Master-Testrunner (Layout + API + Custom) |
~/rudi-chat/test-checks.json | Custom-Checks (waechst mit jedem /bugfix) |
~/rudi-chat/test-results.json | Letztes Test-Ergebnis (JSON) |
~/layout-tests/ | Screenshots aller Seiten (Desktop + Mobile) |
~/.claude/skills/bugfix/skill.md | Bugfix-Skill Definition |
~/.claude/skills/test/skill.md | Test-Skill Definition |
Server-Setup
| Komponente | Detail |
|---|---|
| Hosting | Hostinger VPS (Ubuntu) |
| Domain | rudi-regiofrucht.de |
| SSL | Let's Encrypt (Auto-Renewal) |
| Webserver | Nginx (Reverse Proxy) |
| Backend | Node.js + Express 5 (Port 3456, nur localhost) |
| Service | systemd: rudi-chat.service |
| KI | Anthropic Claude API (claude-opus-4-6) |
| Transkription | Whisper (lokal, Modell: small, Deutsch) |
Nginx-Konfiguration
- TLS: Nur TLS 1.2 + 1.3
- HSTS: 1 Jahr + includeSubDomains
- Basic Auth: Global auf allen Routen
- Rate Limiting: 10 Req/Min pro IP auf Chat-API (Burst 5)
- Security Headers: X-Frame-Options, X-Content-Type-Options, XSS-Protection, Referrer-Policy, Permissions-Policy
- Max Upload: 200 MB fuer QMS, 50 MB fuer Chat-Uploads
- Proxy Timeouts: 300s Chat (SSE), 120s QMS, 60s Transcribe
Sicherheit
Sicherheitsmassnahmen
- Pfad-Traversal-Schutz:
path.resolve() + startsWith()auf allen Dateioperationen - Basic Auth: Alle Webseiten geschuetzt
- Firewall: UFW deny-by-default, SSH + HTTPS offen, RDP nur von Heim-IP
- fail2ban: SSH + Nginx-Auth + Bot-Schutz (3 Jails)
- Node.js: Lauscht nur auf 127.0.0.1 (nicht extern erreichbar)
- Secrets: In
/etc/environment, nie in Dateien oder Chat
Versionierung & Rollback
Alle Code-Verzeichnisse sind mit Git versioniert. Vor jeder Aenderung wird committed – so kann jeder Stand wiederhergestellt werden.
Git-Repositories
| Repo | Pfad | Inhalt |
|---|---|---|
| Backend | ~/rudi-chat/ | Server, Routes, Tools, Chat-Frontend |
| Frontend | /var/www/html/ | Dashboard, Doku, System-Monitor |
| QMS | /var/www/qms/ | QMS-Dashboard, Gap-Analyse |
Die .gitignore schliesst automatisch aus: node_modules/, chat-history/, qms-annotations.json, qms-recurring.json, Backups und Logs.
Aenderungen sichern
# Status pruefen (welche Dateien geaendert?)
cd ~/rudi-chat && git status
# Aenderungen ansehen
git diff
# Commit erstellen (vor weiteren Aenderungen!)
git add -A && git commit -m "Beschreibung der Aenderung"
Rollback: Code zuruecksetzen
# Einzelne Datei zuruecksetzen
git checkout -- server.js
# ALLE Aenderungen verwerfen (zurueck zum letzten Commit)
git checkout .
# Zu einem bestimmten Commit zurueckspringen
git log --oneline # Commits auflisten
git checkout abc1234 . # Alles auf Stand abc1234 setzen
# Letzten Commit rueckgaengig machen (Aenderungen bleiben als unstaged)
git revert HEAD
Nginx-Backup
Nginx-Config ist kein Git-Repo (liegt unter /etc/). Dafuer gibt es ein Backup-Skript:
# Backup erstellen (vor Nginx-Aenderungen!)
~/bin/backup-nginx.sh "beschreibung"
# Backups auflisten
ls ~/backups/nginx/
# Zuruecksetzen
sudo cp ~/backups/nginx/nginx-XXXXXX.conf /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
Es werden automatisch die letzten 20 Backups behalten, aeltere werden geloescht.
System-Status pruefen
# Gesamtstatus: Git-Stand aller Repos + Services
~/bin/rudi-status.sh
Zeigt fuer jedes Repo den letzten Commit, ob ungesicherte Aenderungen vorliegen, Nginx-Backups und den Service-Status.
Workflow bei System-Aenderungen
~/bin/rudi-status.sh– Aktuellen Stand pruefengit add -A && git commit -m "..."– Sauberen Punkt setzen~/bin/backup-nginx.sh "..."– Falls Nginx betroffen- Aenderungen durchfuehren
- Testen (
sudo nginx -t,node ~/bin/layout-test.js) - Wenn OK: neuer Commit. Wenn nicht:
git checkout .
Wartung
Service-Befehle
# Backend neustarten
sudo systemctl restart rudi-chat
# Logs anzeigen
sudo journalctl -u rudi-chat -f
# Nginx pruefen & laden
sudo nginx -t && sudo systemctl reload nginx
# Pipeline neustarten
sudo systemctl restart regio-pipeline
sudo journalctl -u regio-pipeline -f
# Layout-Tests
node ~/bin/layout-test.js
node ~/bin/layout-test.js --mobile
node ~/bin/layout-test.js --verbose
# Tree.json aktualisieren
bash ~/bin/generate-tree.sh
# System-Status (Git + Services)
~/bin/rudi-status.sh
# Nginx-Backup erstellen
~/bin/backup-nginx.sh "beschreibung"
Wichtige Dateien
| Datei | Zweck |
|---|---|
~/rudi-chat/qms-annotations.json | QMS-Tasks und Notizen |
~/rudi-chat/qms-recurring.json | Wiederkehrende Aufgaben |
~/rudi-chat/chat-history/*.json | Chat-Verlaeufe |
~/pipeline/pipeline.db | Pipeline-Datenbank (SQLite) |
~/pipeline/pipeline.py | Pipeline-Hauptprozess (Watchdog) |
~/dokumente/ | Dokumentenablage (Eingang, Verarbeitung, Archiv) |
/var/www/dateien/tree.json | Dateibrowser-Baumstruktur |
/etc/nginx/sites-enabled/default | Nginx-Konfiguration |
/etc/environment | API-Keys und Tokens |
RUDI v2.1 · Regio Frucht GmbH · Stand: 14. Maerz 2026
Erstellt mit Claude Code