Olympus/README-DEV.md
2026-07-05 13:41:33 +02:00

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:

  1. Browser auf http://localhost:3001 oeffnen.
  2. Mit dem initialen Admin oder einem bestehenden Benutzer anmelden.
  3. 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_URL kann auf die Website-Route zeigen, z. B. https://test.funktechnik-schubert.de/status.
  • Ab v0.8.4 kann die Basis-URL im Adminbereich unter /settings gepflegt 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:

  • prepared
  • transferred
  • booked
  • cancelled

Benachrichtigungen:

  • Vorlagen liegen in backend/hermes/app/services/repair_notification_service.py.
  • repair_notification_events dokumentiert jeden Versandversuch.
  • Beim Statuswechsel wird automatisch eine Statusmail verarbeitet.
  • Ohne SMTP-Konfiguration bleibt der Statuswechsel erfolgreich; der Versandversuch wird als skipped dokumentiert.
  • SMTP wird bevorzugt ueber /settings konfiguriert. SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, SMTP_FROM_EMAIL, SMTP_FROM_NAME und SMTP_USE_TLS bleiben als Env-Fallback erhalten.
  • SMTP_PASSWORD wird 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_settings und wird in Responses/Audits maskiert.

Reparaturdokumente:

  • Ab v0.8.5 koennen Dokumente und Bilder direkt an Reparaturen gepflegt werden.
  • Hermes speichert Uploads ueber StorageService unter repairs/<repair_id>/documents.
  • Erlaubte Dateitypen: JPG, PNG, WEBP und PDF.
  • Metadaten liegen in repair_documents; Dateiinhalte liegen nie im Git oder in public.
  • visibility ist mit internal und customer vorbereitet. 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 /settings mit 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/approve
    • POST /public/repairs/status/{token}/estimate/decline
    • POST /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,50 und 1.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_items speichert 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 .env korrekt 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.sh ausfuehren.
  • docker compose restart hermes.

Athena nicht erreichbar:

  • docker compose ps pruefen.
  • Port 3001 auf dem Rechner pruefen.
  • scripts/healthcheck.sh ausfuehren.

MacBook und Mac mini parallel

Empfehlung:

  • .env pro Rechner lokal pflegen und nicht committen.
  • STORAGE_HOST_PATH pro 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