# perinco CRM Backend # Kopie als .env anlegen und Werte setzen. .env niemals committen. PORT=5006 # Nur lokal binden - von aussen erreichbar ist die App ausschliesslich # ueber den Apache-Reverse-Proxy. HOST=127.0.0.1 DB_HOST=localhost DB_PORT=3306 DB_USER=root DB_PASSWORD=changeme DB_NAME=perinco_CRM # Signiert die JWT-Sessions. Muss ein langer Zufallswert sein. JWT_SECRET=changeme-langer-zufallswert JWT_EXPIRES_IN=12h # Wird beim ersten Start angelegt, falls noch kein Benutzer existiert. ADMIN_USERNAME=admin ADMIN_NAME=Administrator ADMIN_EMAIL=admin@perinco.de ADMIN_PASSWORD=changeme-starkes-passwort # Das Diktat braucht hier keine Konfiguration: Whisper laeuft im Browser des # Benutzers, eingestellt wird es im Reiter "Whisper" der Anwendung. # --------------------------------------------------------------------------- # Postfachanbindung Microsoft 365 (crm@perinco.de) # --------------------------------------------------------------------------- # Lesender Zugriff ueber Microsoft Graph mit App-only-Berechtigung # (Client Credentials). Benoetigt wird in Entra genau eine # Anwendungsberechtigung: Mail.Read, mit Administratorzustimmung. Kein # Schreibzugriff, kein Redirect-URI, kein interaktiver Login. # # Fehlen diese Werte, startet das CRM normal - die Postfachanbindung meldet in # den Einstellungen, welche Angabe fehlt, und der Abgleich bleibt aus. # # In Exchange Online zusaetzlich den Zugriff auf dieses eine Postfach begrenzen, # sonst darf die App jedes Postfach im Tenant lesen: # New-ApplicationAccessPolicy -AppId ` # -PolicyScopeGroupId crm@perinco.de -AccessRight RestrictAccess ` # -Description "perinco CRM: nur crm@perinco.de" MS_TENANT_ID= MS_CLIENT_ID= MS_CLIENT_SECRET= MS_MAILBOX=crm@perinco.de # Ordner im Postfach. "inbox" ist ein von Graph vorgegebener Name. # MS_MAIL_FOLDER=inbox # Hintergrundabgleich. Standard ist AN; nur "false" schaltet ihn hart ab. # Intervall, Zeitraum und automatische Kontaktuebernahme stehen dagegen in den # Einstellungen der Anwendung (Tabelle crm_settings). MAIL_SYNC=true # Bremse fuer den Erstabgleich: so viele Delta-Seiten holt ein Lauf hoechstens. # Der naechste Lauf setzt an derselben Stelle fort. # MAIL_MAX_PAGES=20 # Obergrenze fuer den gespeicherten Mailtext je Nachricht (Zeichen). # MAIL_MAX_BODY_CHARS=400000 # --------------------------------------------------------------------------- # Projekt Scanner (portiert, laeuft parallel zur alten App) # --------------------------------------------------------------------------- # Diese Instanz ist vollstaendig eigenstaendig: eigene Datenbank, eigener # Schluessel, eigenes Upload-Verzeichnis, eigener Scheduler. Sie fasst die Daten # des alten Scanners nicht an. # Eigene Datenbank - wird beim Start automatisch angelegt, falls sie fehlt. # NICHT auf project_scanner zeigen lassen, das ist die Datenbank der alten App. SCANNER_DB_NAME=perinco_scanner # SCANNER_DB_HOST=localhost # SCANNER_DB_PORT=3306 # SCANNER_DB_USER=root # SCANNER_DB_PASSWORD= # Eigener Schluessel fuer die Portal-Passwoerter, unabhaengig von der alten App. # Langer Zufallswert, z. B.: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" SCANNER_ENCRYPTION_KEY= # Eigenes Verzeichnis fuer die CV-PDFs. Leer = /uploads. SCANNER_UPLOAD_DIR= # Hintergrund-Scraper (Playwright + OpenAI). Standard ist AN; nur "false" # schaltet ihn ab. Achtung: solange die alte App laeuft, bewerten beide Instanzen # dieselben Projekte unabhaengig voneinander - die OpenAI-Kosten fallen doppelt an. SCANNER_SCHEDULER=true # Minuten Versatz fuer den allerersten Lauf dieser Instanz. Verhindert, dass # beide Scanner gleichzeitig mit denselben Portal-Sessions losziehen (CAPTCHA). # Greift nur, solange noch kein Lauf stattgefunden hat - danach traegt der in der # Datenbank gespeicherte Zeitpunkt (last_scan_at) den Zeitplan ueber Neustarts # hinweg. 0 = sofort loslegen. SCANNER_SCHEDULER_OFFSET=30 # Fallback fuer den OpenAI-Key; bevorzugt wird der Wert aus den Einstellungen. # OPENAI_API_KEY= # --- Einmalige Uebernahme aus der alten Scanner-Datenbank --- # npm run scanner:import [-- --with-matches] [-- --force] [-- --dry-run] LEGACY_DB_NAME=project_scanner # LEGACY_DB_HOST / _PORT / _USER / _PASSWORD (leer = CRM-Werte von oben) # Verzeichnis der CV-PDFs der alten App - von dort werden die Dateien kopiert. # LEGACY_UPLOAD_DIR=/opt/project-scanner/backend/uploads # ENCRYPTION_KEY der alten App - nur damit koennen die Portal-Passwoerter # uebernommen (und hier neu verschluesselt) werden. # LEGACY_ENCRYPTION_KEY=