13 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.
Ab dem Buchhaltungsworkflow wird die UI-Aktion neutral als In Buchhaltung übernehmen gefuehrt. Der Benutzer kopiert Kundendaten und Positionen in Lexware Office, sevdesk oder eine andere Buchhaltungssoftware und markiert die Vorbereitung danach als transferred. Optional kann eine Buchhaltungsnotiz wie Lexware RG-2026-154 gespeichert werden.
Exportstatus:
preparedtransferredbookedcancelled
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