Files
craftvia/.env.example
T
msolarczekandClaude Opus 5 213bcca3a1 L13 Planung: Geocoding der Objekte über OpenStreetMap Nominatim
Provider-Interface (nominatim|none), strukturierte Suche mit User-Agent und Accept-Language, Drosselung 1/s je Prozess, Job geocode-site (Worker: Concurrency 1 + Limiter), Cache am Objekt, manuelle Koordinaten bleiben, Auslöser Anlage/Adressänderung/Import-Bestätigung nur per Queue, Backfill-Skript, Env-Beispiele. Tests mit Fake-Provider, Nominatim nie aufgerufen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:13:26 +02:00

157 lines
7.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# --- Datenbank ---
POSTGRES_USER=craftvia
POSTGRES_PASSWORD=craftvia
POSTGRES_DB=craftvia
DATABASE_URL=postgresql://craftvia:craftvia@localhost:5432/craftvia?schema=public
# --- Row Level Security (F-04) –€” lokal AUS (Owner-Betrieb) ---
# Lokal bleibt RLS aus: Der Owner craftvia ist Superuser/BYPASSRLS und sieht trotz
# FORCE alle Daten. Zum scharfen Testen die beiden Zeilen aktivieren (die Rolle
# craftvia_app zuvor mit LOGIN+Passwort versehen, s. scripts/test-rls-enforcement.ts):
# RLS_ENFORCED=true
# RLS_DATABASE_URL=postgresql://craftvia_app:craftvia_app_local@localhost:5432/craftvia?schema=public
# --- Redis (BullMQ) ---
# F-18: Redis läuft mit requirepass. REDIS_PASSWORD muss zum docker-compose-Default
# passen; das Passwort steht zusätzlich in der REDIS_URL (redis://:<pw>@host:port).
REDIS_PASSWORD=craftvia-redis
REDIS_URL=redis://:craftvia-redis@localhost:6379
# --- Objektspeicher (Garage / S3-kompatibel) ---
# Sind alle vier S3_*-Pflichtvariablen gesetzt, nutzt der Storage-Adapter das echte
# S3-Backend (Byte-Speicherung + Download-Route /files/<key>). Fehlt eine davon, faellt
# der Adapter auf den Stub zurueck (nur Metadaten, keine Bytes) - kein Crash.
# Der Bucket wird NICHT automatisch angelegt (Garage bedient kein S3-CreateBucket): er
# muss vorab provisioniert sein (Compose-Service "garage-provision"). Fehlt er, wirft der
# Adapter einen sprechenden Konfigurationsfehler.
# Garage erzwingt das Key-Format: S3_ACCESS_KEY = "GK" + 24 Hex, S3_SECRET_KEY = 64 Hex.
S3_ENDPOINT=http://localhost:3900
S3_ACCESS_KEY=GKdead0000beef0000cafe0000
S3_SECRET_KEY=0000000000000000000000000000000000000000000000000000000000000001
S3_BUCKET=craftvia-documents
# Region beidseitig us-east-1 (deckt sich mit garage.toml s3_region). forcePathStyle ist
# im Code fest gesetzt - Garage bedient ausschliesslich Path-Style.
S3_REGION=us-east-1
# Garage-Daemon-Secrets (der Daemon liest sie aus der Env, NICHT aus deploy/garage.toml).
# Lokale Dev-Werte (unkritisch, nur localhost). Fuer eigene Stacks frisch erzeugen:
# openssl rand -hex 32
GARAGE_RPC_SECRET=0000000000000000000000000000000000000000000000000000000000000002
GARAGE_ADMIN_TOKEN=0000000000000000000000000000000000000000000000000000000000000003
# --- Backup-Zielspeicher (optional) ---
# Lane „Konfigurierbarer Backup-Zielspeicher": das Ziel der Backup-/DSGVO-Artefakte ist
# jetzt im Betreiber-Portal (/admin/backup) waehlbar (Lokal/S3) und wird in der DB
# gespeichert. Praezedenz zur Laufzeit: DB-Config → diese Env-Vars → lokaler Default.
# Ohne DB-Config gelten weiter S3_* (siehe oben) bzw. — falls unvollstaendig — der
# lokale Ordner unten. HINWEIS: sobald im Portal ein Ziel gespeichert wird, hat die
# DB-Config Vorrang vor S3_*/BACKUP_LOCAL_DIR.
# Lokaler Ordner fuer Backup-Artefakte (Dev: relativ zum cwd). In Prod auf ein
# gemountetes, persistentes Volume zeigen lassen (sonst beim Redeploy fluechtig).
BACKUP_LOCAL_DIR=.backups
# --- Auth ---
AUTH_SECRET=change-me-generate-with-openssl-rand-base64-32
# PASSWORD_PEPPER (Härtung §1): 32-Byte hex, pro Umgebung eindeutig. openssl rand -hex 32
# ⚠ NICHT rotierbar ohne Passwort-Reset für alle; NICHT aus AUTH_SECRET ableiten; NICHT ins Backup-Artefakt.
PASSWORD_PEPPER=change-me-openssl-rand-hex-32
AUTH_URL=http://localhost:3000
# --- KI-Provider (anthropic | openai) ---
AI_PROVIDER=anthropic
AI_API_KEY=
# --- Anthropic (Lotse KI-Assistent, Auftragsimport) ---
# Ohne ANTHROPIC_API_KEY ist die KI-Anbindung deaktiviert (graceful degradation):
# kein Entwurf, Status bleibt –€žmanuell zu erfassen", die UI funktioniert weiter.
ANTHROPIC_API_KEY=
# Optionale Modell-ID; Default: claude-opus-5
ANTHROPIC_MODEL=claude-opus-5
# --- E-Mail / SMTP (SEC1) ---
# Dev: Mailpit oder Mailhog (docker-compose Service `mailhog`, SMTP auf 1025,
# Weboberflaeche auf 8025). Gegen localhost wird TLS bewusst nicht erzwungen.
# Prod: dedizierte Absenderdomain mit SPF, DKIM und DMARC –€” Vorbedingung vor
# dem ersten Produktivversand. Secrets ausschliesslich aus dem Secret-Store.
SMTP_HOST=localhost
SMTP_PORT=1025
# true = implizites TLS (Port 465), false = STARTTLS (587). Ohne Angabe wird
# aus dem Port abgeleitet.
SMTP_SECURE=false
SMTP_USER=
SMTP_PASSWORD=
# Absenderadresse und Anzeigename. MAIL_FROM/MAIL_FROM_NAME werden als Alias
# ebenfalls akzeptiert.
SMTP_FROM=no-reply@craftvia.de
MAIL_FROM_NAME=Craftvia
# Optionale Antwortadresse (sonst keine Reply-To-Kopfzeile).
MAIL_REPLY_TO=
# Basis fuer absolute Links in Mails. Faellt auf AUTH_URL zurueck.
APP_BASE_URL=http://localhost:3000
# --- Craftvia: KI-Extraktion (Auftragsimport) & Lotse ---
# Nutzt ANTHROPIC_API_KEY / ANTHROPIC_MODEL (s. oben). Ohne Key: manuelle Erfassung.
AI_EXTRACTION_PROVIDER=anthropic
# --- Craftvia: Transkription von Sprachnotizen (Whisper-kompatible API) ---
# Ohne TRANSCRIPTION_API_KEY bleibt die Transkription deaktiviert (Status "disabled").
TRANSCRIPTION_PROVIDER=openai-compatible
TRANSCRIPTION_API_URL=https://api.openai.com/v1/audio/transcriptions
TRANSCRIPTION_API_KEY=
TRANSCRIPTION_MODEL=whisper-1
# --- Craftvia: optionaler Malware-Scan für Uploads (ClamAV clamd) ---
# Leer = nur Allowlist/Magic-Byte-Prüfung; gesetzt = zusätzlich clamd INSTREAM.
CLAMAV_HOST=
CLAMAV_PORT=3310
# --- Craftvia: Berichts-PDF (Worker, playwright-core + Chromium) ---
# Leer = Playwright-Chromium bzw. lokal installiertes Google Chrome (Entwicklerrechner).
# Im Docker-Worker-Image fest /usr/bin/chromium.
PDF_CHROMIUM_PATH=
# --- Craftvia: Offline/PWA ---
# Ab wie vielen Tagen ein lokal gespeichertes Auftragsbundle als veraltet gilt (1–365).
OFFLINE_MAX_DAYS=7
# --- Craftvia: Rate Limits der REST-API (je Nutzer, Anfragen pro Minute) ---
# Allgemein für /api/v1/**.
API_RATE_LIMIT_PER_MINUTE=300
# Einsatz-/Sync-Endpunkte (/api/v1/sync, /api/v1/uploads, /api/v1/field/**) – höher, weil
# die PWA nach Offline-Phasen Outbox und Fotos in Schüben nachsendet.
API_FIELD_RATE_LIMIT_PER_MINUTE=1200
# --- Craftvia: KI-Protokoll & Kostenbremse ---
# Nach N Tagen leert/pseudonymisiert ein Worker-Job Ein-/Ausgaben im KI-Protokoll
# (AiGeneration); Metadaten (Art, Modell, Tokens, Zeitpunkt) bleiben erhalten.
AI_GENERATION_RETENTION_DAYS=180
# Tokens (ein + aus) je Mandant je Kalendermonat; darüber lehnen Lotse und
# Import-Extraktion ab. 0 = unbegrenzt.
AI_MONTHLY_TOKEN_LIMIT=0
# --- Craftvia: Planung – Karten & Geocoding (L13) ---
# Adresse → Koordinaten nur serverseitig im Worker (Job geocode-site, max. 1 Anfrage/s),
# Ergebnis wird am Objekt gespeichert. nominatim | none (none = keine Verortung, Objekte
# erscheinen „ohne Ortsangabe“). Für Produktion eigenen/vertraglichen Dienst verwenden.
GEOCODING_PROVIDER=nominatim
# GEOCODING_URL=https://nominatim.openstreetmap.org
# Eindeutiger User-Agent (Nominatim-Richtlinie); leer = "Craftvia/<version> (+APP_BASE_URL)".
# GEOCODING_USER_AGENT=
# Kartenkacheln der Live-Lage; der Host wird beim Build in die CSP (img-src) übernommen.
# MAP_TILE_URL=https://tile.openstreetmap.org/{z}/{x}/{y}.png
# MAP_ATTRIBUTION=© OpenStreetMap-Mitwirkende
# --- Optionale Fundament-Variablen (Default leer) ---
# MFA_ENC_KEY: Schlüssel für TOTP-Secrets at-rest (leer = aus AUTH_SECRET abgeleitet).
# ⚠ Nach dem Setzen nicht mehr ändern.
# MFA_ENC_KEY=
# BACKUP_ENC_KEY: Verschlüsselung der Backup-Artefakte (leer = AUTH_SECRET).
# BACKUP_ENC_KEY=
# WebAuthn/Passkeys: Origin und RP-ID (leer = aus AUTH_URL abgeleitet).
# WEBAUTHN_ORIGIN=http://localhost:3000
# WEBAUTHN_RP_ID=localhost
# Demo-Seed-Passwort (Default Demo1234!).
# SEED_PASSWORD=
# RLS-Test hart statt Skip, wenn craftvia_app kein LOGIN hat (CI).
# RLS_TEST_REQUIRED=true