Files
craftvia/.env.example
T
msolarczekandClaude Opus 5 bf4456718e Architektur: Craftvia-Domänenmodell, Verträge und Team-Schnitte
- Migration 0002_craftvia_domain: 27 Fachtabellen inkl. RLS (enable_tenant_rls)
- TENANT_MODELS (db.ts, backup/topology.ts) um alle Fachmodelle ergänzt
- moduleGuard liefert DB-autoritative Rechte; ServiceCtx für Domänen-Services
- Verträge: Statusmaschine, Events, Nummernkreise, Sichtbarkeits-Scopes,
  Job-Queues + Worker, KI-Provider-Interfaces, Sync-Envelope
- docs/craftvia/ARCHITEKTUR.md mit Lanes, Ownership und DoD

Gate: tsc, lint, build, 22/22 Tests grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 11:49:21 +02:00

106 lines
5.1 KiB
Bash

# --- 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) ---
CLAMAV_HOST=
CLAMAV_PORT=3310