12 KiB
Olympus CRM Entwicklungssetup
Dieses Dokument beschreibt das lokale Setup fuer neue Rechner und parallele Entwicklung auf mehreren Macs.
Setup auf neuem Mac
Voraussetzungen:
- Git
- Docker Desktop
- Node.js passend zu Athena
- Python/uv fuer lokale Hermes-Checks
Repository klonen:
git clone <repository-url> Olympus
cd Olympus
Umgebung anlegen:
cp .env.example .env
Wichtige lokale Werte:
AUTH_COOKIE_SECURE=false
ATHENA_PUBLIC_ORIGIN=http://localhost:3001
STORAGE_PROVIDER=local
STORAGE_BASE_PATH=/data/storage
STORAGE_MAX_UPLOAD_MB=50
STORAGE_HOST_PATH=./storage
OLYMPUS_REPAIR_INTAKE_TOKEN=
PUBLIC_REPAIR_STATUS_BASE_URL=
SMTP_HOST=
SMTP_PORT=587
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_FROM_EMAIL=
SMTP_FROM_NAME=Funktechnik Schubert
SMTP_USE_TLS=true
LEXWARE_ENABLED=false
LEXWARE_API_BASE_URL=https://api.lexware.io
LEXWARE_API_KEY=
PUBLIC_REPAIR_STATUS_BASE_URL und die SMTP-Werte sind ab v0.8.4 Fallbacks. Bevorzugt wird die Admin-Konfiguration in Olympus unter /settings. Fuer Apple Mail/iCloud gilt: smtp.mail.me.com, Port 587, TLS/STARTTLS aktiv, Benutzername = vollstaendige Mailadresse, Passwort = app-spezifisches Passwort.
LEXWARE_* ist ab v0.8.9 nur ein Env-Fallback. Bevorzugt wird die Lexware-Konfiguration im Adminbereich unter /settings -> Lexware Office. Der API-Key darf nicht ins Git und wird nie an Athena zurueckgegeben.
Wenn SECRET_KEY Sonderzeichen wie $ enthaelt, den Wert in der Shell oder Compose-Umgebung korrekt quoten. Secrets gehoeren nicht ins Git.
Docker Netzwerk
Das gemeinsame Compose-File nutzt ein externes Docker-Netzwerk:
docker network create olympus-network
Wenn das Netzwerk bereits existiert, meldet Docker das nur als Hinweis.
Docker Compose Start
docker compose build
docker compose up -d
Hermes ist im gemeinsamen Stack nur intern im Docker-Netzwerk erreichbar. Athena ist lokal ueber den Browser erreichbar:
- Athena:
http://localhost:3001 - Hermes intern:
http://hermes:8000
Der Browser spricht nicht direkt mit Hermes.
Migrationen
Migrationen ausfuehren:
scripts/migrate.sh
Alternativ lokal im Backend:
cd backend/hermes
uv run alembic upgrade head
Initial Admin
Fuer neue Installationen ohne aktive Benutzer kann Hermes beim Startup einen initialen Admin anlegen.
INITIAL_ADMIN_USERNAME=admin
INITIAL_ADMIN_EMAIL=admin@example.local
INITIAL_ADMIN_PASSWORD=<lokales-passwort>
INITIAL_ADMIN_FIRST_NAME=
INITIAL_ADMIN_LAST_NAME=
Diese Werte nur lokal oder sicher auf dem Zielsystem setzen. Nach dem ersten produktiven Login sollte das Passwort geaendert und die Bootstrap-Variablen wieder entfernt werden.
Login
Nach Start und Migration:
- Browser auf
http://localhost:3001oeffnen. - Mit dem initialen Admin oder einem bestehenden Benutzer anmelden.
- Athena setzt das HttpOnly-Cookie. Hermes setzt keine Browser-Cookies.
Storage
Neue Dateiablagen laufen ueber das Storage Framework.
Lokaler Standard:
STORAGE_HOST_PATH=./storage
STORAGE_BASE_PATH=/data/storage
VPS-Empfehlung:
STORAGE_HOST_PATH=/opt/olympus-storage
STORAGE_BASE_PATH=/data/storage
Bestehende Knowledge-Dateien aus alten Setups unter /data/knowledge werden nicht automatisch verschoben. Vor einer manuellen Migration immer Backup erstellen.
Knowledge Workflow
Die Wissensdatenbank folgt lokal und produktiv diesem Ablauf:
Hersteller -> Gerät -> Dokument -> Notiz/Reparaturhinweis
Hermes legt beim Startup Standard-Hersteller an, wenn sie noch fehlen. Danach koennen Geraete angelegt werden. Dokumentuploads sind erst sinnvoll, wenn Hersteller und Geraet vorhanden sind; Athena blockiert unvollstaendige Uploads direkt im Formular.
Reparaturmanagement
Das Reparaturmodul ist ab v0.8.0 aktiv.
Lokaler Ablauf:
cd backend/hermes
SECRET_KEY=local-check uv run alembic upgrade head
Athena erreicht Reparaturen ausschliesslich ueber BFF-Routen:
/api/repairs/api/repairs/[id]/api/repairs/[id]/documents/api/repairs/[id]/documents/upload/api/repairs/[id]/documents/[documentId]/api/repairs/[id]/documents/[documentId]/download/api/repairs/[id]/status/api/repairs/[id]/history/api/repairs/[id]/public-link/api/repairs/[id]/notifications/api/repairs/[id]/send-status-mail
Hermes stellt zusaetzlich POST /public/repair-intake fuer die spaetere Website-Anbindung bereit. Der Endpunkt ist fuer Server-zu-Server-Kommunikation gedacht und erwartet X-Olympus-Intake-Token. Der Token wird ueber OLYMPUS_REPAIR_INTAKE_TOKEN gesetzt und darf nicht im Browser verwendet werden.
Ab v0.8.1 zeigt Athena deutsche Statuslabels, waehrend die API-Statuscodes englisch und stabil bleiben. Statuswechsel werden als Timeline mit Benutzer, Datum und Notiz angezeigt.
Statuslink-Konzept:
- Interne Verwaltung ueber
GET|POST|DELETE /repairs/{id}/public-link. - RBAC-Permission:
repairs.public_link.manage. - Tokens sind lang, zufaellig und werden nur gehasht gespeichert.
- Der Klartexttoken wird nur einmal bei Erstellung zurueckgegeben.
PUBLIC_REPAIR_STATUS_BASE_URLkann auf die Website-Route zeigen, z. B.https://test.funktechnik-schubert.de/status.- Ab v0.8.4 kann die Basis-URL im Adminbereich unter
/settingsgepflegt werden; die Env Var bleibt Fallback. - Oeffentliche Statusdaten kommen spaeter ueber
GET /public/repairs/status/{token}. - Die Antwort enthaelt keine Kundendaten, keine internen Notizen und keine nicht freigegebenen Diagnosen.
Lexware Office Foundation
Ab v0.8.9 ist eine Lexware-Office-Grundlage vorbereitet.
Rollenverteilung:
- Olympus bleibt Werkstatt-ERP und verwaltet Kunden-, Reparatur-, Lager- und KV-Daten.
- Lexware Office bleibt fuehrend fuer Buchhaltung, Rechnungen, Steuer, DATEV und EÜR.
Konfiguration:
- Adminbereich:
/settings -> Lexware Office - Hermes-Endpunkte:
GET|PUT /lexware/settings,POST /lexware/test-connection - Athena-BFF:
/api/lexware/settings,/api/lexware/test-connection - Env-Fallback:
LEXWARE_ENABLED,LEXWARE_API_BASE_URL,LEXWARE_API_KEY
Der Verbindungstest nutzt serverseitig GET {LEXWARE_API_BASE_URL}/v1/profile mit Bearer API-Key. Browser rufen weder Hermes noch Lexware direkt auf.
Freigegebene Kostenvoranschlaege koennen manuell fuer Lexware vorbereitet werden:
POST /api/repairs/[id]/estimates/[estimateId]/lexware/prepare-invoice
v0.8.9 erstellt noch keine echte Rechnung automatisch. Die Aktion erzeugt eine validierte Payload-Zusammenfassung, Mapping-Informationen und einen lexware_sync_records-Eintrag.
Benachrichtigungen:
- Vorlagen liegen in
backend/hermes/app/services/repair_notification_service.py. repair_notification_eventsdokumentiert jeden Versandversuch.- Beim Statuswechsel wird automatisch eine Statusmail verarbeitet.
- Ohne SMTP-Konfiguration bleibt der Statuswechsel erfolgreich; der Versandversuch wird als
skippeddokumentiert. - SMTP wird bevorzugt ueber
/settingskonfiguriert.SMTP_HOST,SMTP_PORT,SMTP_USERNAME,SMTP_PASSWORD,SMTP_FROM_EMAIL,SMTP_FROM_NAMEundSMTP_USE_TLSbleiben als Env-Fallback erhalten. SMTP_PASSWORDwird nicht an Athena zurueckgegeben und gehoert nie ins Git oder in Logs.- Verschluesselung at rest ist fuer v0.8.x vorbereitet/geplant; bis dahin bleibt das Passwort serverseitig in
system_settingsund wird in Responses/Audits maskiert.
Reparaturdokumente:
- Ab v0.8.5 koennen Dokumente und Bilder direkt an Reparaturen gepflegt werden.
- Hermes speichert Uploads ueber
StorageServiceunterrepairs/<repair_id>/documents. - Erlaubte Dateitypen: JPG, PNG, WEBP und PDF.
- Metadaten liegen in
repair_documents; Dateiinhalte liegen nie im Git oder inpublic. visibilityist mitinternalundcustomervorbereitet. In v0.8.5 gibt es noch keine oeffentliche Kundenanzeige fuer diese Dateien.- PDF-Dateien koennen inline oder als Download ueber Athena-BFF geoeffnet werden; ein vollstaendiger PDF-Viewer ist ein Folgefeature.
Kostenvoranschlaege:
- Ab v0.8.6 koennen KVs direkt auf der Reparaturdetailseite erstellt, bearbeitet, gesendet, storniert und geloescht werden.
- Athena nutzt ausschliesslich BFF-Routen unter
/api/repairs/[id]/estimates. - Hermes berechnet alle Summen serverseitig. Client-Summen sind nur Vorschau.
- Nummernformat:
KV<jahr>-000001. - Der Versand nutzt die bestehende SMTP-Konfiguration aus
/settingsmit Env-Fallback. - Der Versand erzeugt/erneuert einen sicheren Public-Statuslink und sendet ihn an
customer_email. GET /public/repairs/status/{token}liefert aktive/gesendete KV-Daten ohne interne Notizen.- Public-Entscheidungen laufen ohne Kundenlogin ueber:
POST /public/repairs/status/{token}/estimate/approvePOST /public/repairs/status/{token}/estimate/declinePOST /public/repairs/status/{token}/estimate/question
- Die oeffentliche Website zeigt diese Daten erst nach einer spaeteren Website-Version an. Olympus stellt die API dafuer bereit.
- PDF-Erzeugung, Lexoffice und Rechnungen sind Folgefeatures.
Lager / Ersatzteile
Das Lagermodul ist ab v0.8.7 aktiv.
Migration lokal ausfuehren:
cd backend/hermes
SECRET_KEY=local-check uv run alembic upgrade head
Athena erreicht Lagerdaten ausschliesslich ueber BFF-Routen:
/api/inventory/items/api/inventory/items/search/api/inventory/items/[id]/api/inventory/items/[id]/stock/adjust/api/inventory/items/[id]/stock/reserve/api/inventory/items/[id]/stock/release/api/inventory/items/[id]/stock/consume/api/inventory/items/[id]/movements/api/inventory/categories/api/inventory/categories/[id]/api/inventory/locations/api/inventory/locations/[id]/api/inventory/suppliers/api/inventory/suppliers/[id]
Hermes-Endpunkte liegen unter /inventory/... und sind mit inventory.* Permissions geschuetzt.
Bestandslogik:
- SKU optional; bei leerer SKU erzeugt Hermes
ET-<jahr>-000001. quantity_available = quantity_on_hand - quantity_reserved.- Bestandsanpassungen, Reservierungen, Freigaben und Verbrauch erzeugen
inventory_stock_movements. - Artikel mit Bewegungen werden deaktiviert statt hart geloescht.
- Preise werden intern in cents gespeichert; Athena akzeptiert deutsche Euro-Eingaben wie
1,1,50und1.50.
KV-Integration ab v0.8.8:
- Lagerartikel koennen im KV-Dialog gesucht und als Position uebernommen werden.
- Hermes uebernimmt Verkaufspreis, Einheit, Artikelname, SKU und Hersteller serverseitig.
repair_estimate_itemsspeichert Snapshot-Felder, damit spaetere Lageraenderungen alte KVs nicht veraendern.- Nur gesendete KVs reservieren Bestand.
- Ablehnung, Storno und Loeschung eines gesendeten KV geben Reservierungen frei.
- Freigegebene KVs behalten die Reservierung.
- Automatischer Verbrauch beim Reparaturabschluss ist vorbereitet, aber noch nicht aktiv.
Folgefeatures:
- CSV-Template, Import/Export und Barcode-/QR-Funktionen bleiben vorbereitet, sind aber in v0.8.8 nicht aktiv.
Vorbereitete Website-/Portal-Routen fuer spaeter:
/status/<token>/portal/login
Typische Fehler
Hermes restartet wegen fehlender Migration:
scripts/migrate.sh
docker compose restart hermes
SECRET_KEY mit $ wird falsch interpretiert:
- Wert in
.envkorrekt escapen oder quoten. - Keine Secrets in Commit oder Logs schreiben.
Docker Container Name Conflict:
docker compose down
docker ps -a
Danach blockierenden Altcontainer gezielt entfernen, wenn er wirklich nicht mehr gebraucht wird.
External network fehlt:
docker network create olympus-network
DB leer oder Admin fehlt:
INITIAL_ADMIN_*Werte setzen.scripts/migrate.shausfuehren.docker compose restart hermes.
Athena nicht erreichbar:
docker compose pspruefen.- Port
3001auf dem Rechner pruefen. scripts/healthcheck.shausfuehren.
MacBook und Mac mini parallel
Empfehlung:
.envpro Rechner lokal pflegen und nicht committen.STORAGE_HOST_PATHpro Rechner bewusst setzen.- Datenbank- und Storage-Backups nicht ungeprueft zwischen Rechnern ueberschreiben.
- Vor Branch-Wechseln Migrationen pruefen.
- Bei paralleler Arbeit keine Docker-Volumes loeschen, solange ungesicherte Uploads existieren.
Qualitaetschecks
python3 -m compileall backend/hermes/app
cd frontend/athena
npm run lint
npx next build --webpack
Skripte pruefen:
bash -n scripts/*.sh