cleanup
This commit is contained in:
642
bitbylaw/docs/ARCHITECTURE.md
Normal file
642
bitbylaw/docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,642 @@
|
||||
# Architektur
|
||||
|
||||
## Systemübersicht
|
||||
|
||||
Das bitbylaw-System ist eine event-driven Integration zwischen Advoware, EspoCRM, Google Calendar, Vermieterhelden und 3CX Telefonie, basierend auf dem Motia Framework. Die Architektur folgt einem modularen, mikroservice-orientierten Ansatz mit klarer Separation of Concerns.
|
||||
|
||||
### Kernkomponenten
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ KONG API Gateway │
|
||||
│ api.bitbylaw.com │
|
||||
│ (Auth, Rate Limiting) │
|
||||
└──────────────┬──────────────┘
|
||||
│
|
||||
┌──────────────────────────┼──────────────────────────┐
|
||||
│ │ │
|
||||
┌────▼────────┐ ┌──────▼─────────┐ ┌─────▼──────┐
|
||||
│ Vermieter- │ │ Motia │ │ 3CX │
|
||||
│ helden.de │────────▶│ Framework │◀────────│ Telefonie │
|
||||
│ (WordPress) │ │ (Middleware) │ │ (ralup) │
|
||||
└─────────────┘ └────────┬───────┘ └────────────┘
|
||||
Leads Input │ Call Handling
|
||||
│
|
||||
┌───────────────────────────┼───────────────────────────┐
|
||||
│ │ │
|
||||
┌────▼────┐ ┌──────▼──────┐ ┌──────▼─────┐
|
||||
│Advoware │ │ VMH │ │ Calendar │
|
||||
│ Proxy │ │ Webhooks │ │ Sync │
|
||||
└────┬────┘ └─────┬───────┘ └─────┬──────┘
|
||||
│ │ │
|
||||
│ │ │
|
||||
┌────▼─────────────────────────▼──────────────────────────▼────┐
|
||||
│ Redis (3 DBs) │
|
||||
│ DB 1: Caching & Locks │
|
||||
│ DB 2: Calendar Sync State │
|
||||
└───────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌────▼────────────────────────────┐
|
||||
│ External Services │
|
||||
├─────────────────────────────────┤
|
||||
│ • Advoware REST API │
|
||||
│ • EspoCRM (VMH) │
|
||||
│ • Google Calendar API │
|
||||
│ • 3CX API (ralup.my3cx.de) │
|
||||
│ • Vermieterhelden WordPress │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Komponenten-Details
|
||||
|
||||
### 0. KONG API Gateway
|
||||
|
||||
**Zweck**: Zentraler API-Gateway für alle öffentlichen APIs mit Authentifizierung und Rate Limiting.
|
||||
|
||||
**Domain**: `api.bitbylaw.com`
|
||||
|
||||
**Funktionen**:
|
||||
- **Authentication**: API-Key-basiert, JWT, OAuth2
|
||||
- **Rate Limiting**: Pro Consumer/API-Key
|
||||
- **Request Routing**: Zu Backend-Services (Motia, etc.)
|
||||
- **SSL/TLS Termination**: HTTPS-Handling
|
||||
- **Logging & Monitoring**: Request-Logs, Metrics
|
||||
- **CORS Handling**: Cross-Origin Requests
|
||||
|
||||
**Upstream Services**:
|
||||
- Motia Framework (Advoware Proxy, Calendar Sync, VMH Webhooks)
|
||||
- Zukünftig: Weitere Microservices
|
||||
|
||||
**Konfiguration**:
|
||||
```yaml
|
||||
# KONG Service Configuration
|
||||
services:
|
||||
- name: motia-backend
|
||||
url: http://localhost:3000
|
||||
routes:
|
||||
- name: advoware-proxy
|
||||
paths: [/advoware/*]
|
||||
- name: calendar-sync
|
||||
paths: [/calendar/*]
|
||||
- name: vmh-webhooks
|
||||
paths: [/vmh/*]
|
||||
plugins:
|
||||
- name: key-auth
|
||||
- name: rate-limiting
|
||||
config:
|
||||
minute: 600
|
||||
```
|
||||
|
||||
**Flow**:
|
||||
```
|
||||
Client → KONG (api.bitbylaw.com) → Auth Check → Rate Limit → Motia Backend
|
||||
```
|
||||
|
||||
### 1. Advoware Proxy Layer
|
||||
|
||||
**Zweck**: Transparente REST-API-Proxy für Advoware mit Authentifizierung und Caching.
|
||||
|
||||
**Module**: `steps/advoware_proxy/`
|
||||
- `advoware_api_proxy_get_step.py` - GET-Requests
|
||||
- `advoware_api_proxy_post_step.py` - POST-Requests (Create)
|
||||
- `advoware_api_proxy_put_step.py` - PUT-Requests (Update)
|
||||
- `advoware_api_proxy_delete_step.py` - DELETE-Requests
|
||||
|
||||
**Services**: `services/advoware.py`
|
||||
- Token-Management (HMAC-512 Authentifizierung)
|
||||
- Redis-basiertes Token-Caching (55min Lifetime)
|
||||
- Automatischer Token-Refresh bei 401-Errors
|
||||
- Async API-Client mit aiohttp
|
||||
|
||||
**Datenfluss**:
|
||||
```
|
||||
Client → API-Step → AdvowareAPI Service → Redis (Token Cache) → Advoware API
|
||||
```
|
||||
|
||||
### 2. Calendar Sync System
|
||||
|
||||
**Zweck**: Bidirektionale Synchronisation zwischen Advoware-Terminen und Google Calendar.
|
||||
|
||||
**Architecture Pattern**: Event-Driven Cascade
|
||||
|
||||
**Integration**: EspoCRM sendet Webhooks an KONG → Motia
|
||||
|
||||
**Datenfluss**:
|
||||
```
|
||||
EspoCRM (Vermieterhelden CRM) → KONG → Motia VMH Webhooks → Redis Dedup → Events
|
||||
```
|
||||
```
|
||||
Cron (täglich)
|
||||
→ calendar_sync_cron_step
|
||||
→ Emit: "calendar_sync_all"
|
||||
→ calendar_sync_all_step
|
||||
→ Fetch Employees
|
||||
→ For each Employee:
|
||||
→ Set Redis Lock
|
||||
→ Emit: "calendar_sync_employee"
|
||||
→ calendar_sync_event_step
|
||||
→ Fetch Advoware Events
|
||||
→ Fetch Google Events
|
||||
→ Sync (Create/Update/Delete)
|
||||
→ Clear Redis Lock
|
||||
```
|
||||
|
||||
**Module**: `steps/advoware_cal_sync/`
|
||||
- `calendar_sync_cron_step.py` - Täglicher Trigger
|
||||
- `calendar_sync_all_step.py` - Employee-List-Handler
|
||||
- `calendar_sync_event_step.py` - Per-Employee Sync-Logic
|
||||
- `calendar_sync_api_step.py` - Manueller Trigger-Endpoint
|
||||
- `calendar_sync_utils.py` - Shared Utilities
|
||||
- `audit_calendar_sync.py` - Audit & Diagnostics
|
||||
|
||||
**Key Features**:
|
||||
- **Redis Locking**: Verhindert parallele Syncs für denselben Employee
|
||||
- **Rate Limiting**: Token-Bucket-Algorithm (7 tokens, Redis-based)
|
||||
- **Normalisierung**: Common format (Berlin TZ) für beide APIs
|
||||
- **Error Isolation**: Employee-Fehler stoppen nicht Gesamt-Sync
|
||||
|
||||
**Datenmapping**:
|
||||
```
|
||||
Advoware Format → Standard Format → Google Calendar Format
|
||||
↓ ↓ ↓
|
||||
datum/uhrzeitVon start (datetime) dateTime
|
||||
datumBis end (datetime) dateTime
|
||||
dauertermin all_day (bool) date
|
||||
turnus/turnusArt recurrence RRULE
|
||||
```
|
||||
|
||||
### 3. VMH Webhook System
|
||||
|
||||
**Zweck**: Empfang und Verarbeitung von EspoCRM Webhooks für Beteiligte-Entitäten.
|
||||
|
||||
**Architecture Pattern**: Webhook → Deduplication → Event Emission
|
||||
|
||||
**Module**: `steps/vmh/`
|
||||
- `webhook/beteiligte_create_api_step.py` - Create Webhook
|
||||
- `webhook/beteiligte_update_api_step.py` - Update Webhook
|
||||
- `webhook/beteiligte_delete_api_step.py` - Delete Webhook
|
||||
- `beteiligte_sync_event_step.py` - Sync Event Handler (Placeholder)
|
||||
|
||||
**Webhook-Flow**:
|
||||
```
|
||||
EspoCRM → POST /vmh/webhook/beteiligte/create
|
||||
↓
|
||||
Webhook Step
|
||||
↓
|
||||
Extract Entity IDs
|
||||
↓
|
||||
Redis Deduplication (SET: vmh:beteiligte:create_pending)
|
||||
↓
|
||||
Emit Event: "vmh.beteiligte.create"
|
||||
↓
|
||||
Sync Event Step (subscribes)
|
||||
↓
|
||||
[TODO: Implementierung]
|
||||
|
||||
### 4. Vermieterhelden Integration
|
||||
|
||||
**Zweck**: Lead-Eingang von Vermieterhelden.de WordPress-Frontend.
|
||||
|
||||
**URL**: `https://vermieterhelden.de`
|
||||
|
||||
**Technologie**: WordPress-basiertes Frontend
|
||||
|
||||
**Funktionen**:
|
||||
- **Lead-Formulare**: Mieter, Vermieter, Anfragen
|
||||
- **Lead-Routing**: Zu EspoCRM (VMH) → Motia
|
||||
- **Webhook-basiert**: POST zu KONG/Motia bei neuem Lead
|
||||
|
||||
**Datenfluss**:
|
||||
```
|
||||
Vermieterhelden.de → Lead erstellt → Webhook → KONG → Motia → EspoCRM/Advoware
|
||||
```
|
||||
|
||||
**Lead-Typen**:
|
||||
- Mieter-Anfragen
|
||||
- Vermieter-Anfragen
|
||||
- Kontaktformulare
|
||||
- Newsletter-Anmeldungen
|
||||
|
||||
**Integration mit Motia**:
|
||||
- Eigener Webhook-Endpoint: `/api/leads/vermieterhelden`
|
||||
- Lead-Validierung und -Enrichment
|
||||
- Weiterleitung an CRM-Systeme
|
||||
|
||||
### 5. 3CX Telefonie-Integration
|
||||
|
||||
**Zweck**: Telefonie-System-Integration für Call-Handling und Lead-Qualifizierung.
|
||||
|
||||
**URL**: `https://ralup.my3cx.de`
|
||||
|
||||
**Technologie**: 3CX Cloud PBX
|
||||
|
||||
**Funktionen**:
|
||||
- **Outbound Calls**: Lead-Anrufe (automatisch oder manuell)
|
||||
- **Inbound Calls**: Stammdatenabfrage (CTI - Computer Telephony Integration)
|
||||
- **Call Logging**: Anrufprotokolle zu CRM
|
||||
- **Call Recording**: Aufzeichnungen speichern und abrufen
|
||||
- **Screen Pops**: Kundeninfo bei eingehendem Anruf
|
||||
|
||||
**API-Integrationen**:
|
||||
|
||||
**A) Outbound: Motia → 3CX**
|
||||
```
|
||||
Motia → KONG → 3CX API
|
||||
- Initiate Call to Lead
|
||||
- Get Call Status
|
||||
```
|
||||
|
||||
**B) Inbound: 3CX → Motia**
|
||||
```
|
||||
3CX Webhook → KONG → Motia
|
||||
- Call Started → Fetch Customer Data
|
||||
- Call Ended → Log Call Record
|
||||
```
|
||||
|
||||
**Datenfluss**:
|
||||
|
||||
**Call Initiation**:
|
||||
```
|
||||
Lead in CRM → Trigger Call → Motia → 3CX API → Dial Number
|
||||
```
|
||||
|
||||
**Inbound Call**:
|
||||
```
|
||||
3CX detects call → Webhook to Motia → Lookup in Advoware/EspoCRM → Return data → 3CX Screen Pop
|
||||
```
|
||||
|
||||
**Call Recording**:
|
||||
```
|
||||
Call ends → 3CX Webhook → Motia → Store metadata → Link to CRM entity
|
||||
```
|
||||
|
||||
**Use Cases**:
|
||||
- Lead-Qualifizierung nach Eingang
|
||||
- Stammdatenabfrage bei Anruf
|
||||
- Anrufprotokoll in EspoCRM/Advoware
|
||||
- Automatische Follow-up-Tasks
|
||||
```
|
||||
|
||||
**Deduplikation-Mechanismus**:
|
||||
- Redis SET für pending IDs pro Action-Type (create/update/delete)
|
||||
- Neue IDs werden zu SET hinzugefügt
|
||||
- Events nur für neue (nicht-duplizierte) IDs emittiert
|
||||
- SET-TTL verhindert Memory-Leaks
|
||||
|
||||
## Event-Driven Design
|
||||
|
||||
### Event-Topics
|
||||
|
||||
| Topic | Emitter | Subscriber | Payload |
|
||||
|-------|---------|------------|---------|
|
||||
| `calendar_sync_all` | cron_step | all_step | `{}` |
|
||||
| `calendar_sync_employee` | all_step, api_step | event_step | `{kuerzel, full_content}` |
|
||||
| `vmh.beteiligte.create` | create webhook | sync_event_step | `{entity_id, action, source, timestamp}` |
|
||||
| `vmh.beteiligte.update` | update webhook | sync_event_step | `{entity_id, action, source, timestamp}` |
|
||||
| `vmh.beteiligte.delete` | delete webhook | sync_event_step | `{entity_id, action, source, timestamp}` |
|
||||
|
||||
### Event-Flow Patterns
|
||||
|
||||
**1. Cascade Pattern** (Calendar Sync):
|
||||
```
|
||||
Trigger → Fetch List → Emit per Item → Process Item
|
||||
```
|
||||
|
||||
**2. Webhook Pattern** (VMH):
|
||||
```
|
||||
External Event → Dedup → Internal Event → Processing
|
||||
```
|
||||
|
||||
## Redis Architecture
|
||||
|
||||
### Database Layout
|
||||
|
||||
**DB 0**: Default (Motia internal)
|
||||
**DB 1**: Advoware Cache & Locks
|
||||
- `advoware_access_token` - Bearer Token (TTL: 53min)
|
||||
- `advoware_token_timestamp` - Token Creation Time
|
||||
- `calendar_sync:lock:{kuerzel}` - Per-Employee Lock (TTL: 5min)
|
||||
- `vmh:beteiligte:create_pending` - Create Dedup SET
|
||||
- `vmh:beteiligte:update_pending` - Update Dedup SET
|
||||
- `vmh:beteiligte:delete_pending` - Delete Dedup SET
|
||||
|
||||
**DB 2**: Calendar Sync Rate Limiting
|
||||
- `google_calendar_api_tokens` - Token Bucket for Rate Limiting
|
||||
|
||||
---
|
||||
|
||||
## External APIs
|
||||
|
||||
### Advoware REST API
|
||||
|
||||
**Base URL**: `https://advoware-api.example.com/api/v1/`
|
||||
**Auth**: HMAC-512 (siehe `services/advoware.py`)
|
||||
**Rate Limits**: Unknown (keine Limits bekannt)
|
||||
**Documentation**: [Advoware API Swagger](../docs/advoware/advoware_api_swagger.json)
|
||||
|
||||
**Wichtige Endpoints**:
|
||||
- `POST /auth/login` - Token generieren
|
||||
- `GET /employees` - Employee-Liste
|
||||
- `GET /events` - Termine abrufen
|
||||
- `POST /events` - Termin erstellen
|
||||
- `PUT /events/{id}` - Termin aktualisieren
|
||||
|
||||
### Redis Usage Patterns
|
||||
|
||||
**Token Caching**:
|
||||
```python
|
||||
# Set with expiration
|
||||
redis.set('advoware_access_token', token, ex=3180) # 53min
|
||||
|
||||
# Get with fallback
|
||||
token = redis.get('advoware_access_token')
|
||||
if not token:
|
||||
token = fetch_new_token()
|
||||
```
|
||||
|
||||
### EspoCRM (VMH)
|
||||
|
||||
**Integration**: Webhook Sender (Outbound), API Consumer
|
||||
**Endpoints**: Configured in EspoCRM, routed via KONG
|
||||
**Format**: JSON POST with entity data
|
||||
**Note**: Dient als CRM für Vermieterhelden-Leads
|
||||
|
||||
### 3CX Telefonie API
|
||||
|
||||
**Base URL**: `https://ralup.my3cx.de/api/v1/`
|
||||
**Auth**: API Key oder Basic Auth
|
||||
**Rate Limits**: Unknown (typisch 60 req/min)
|
||||
|
||||
**Key Endpoints**:
|
||||
- `POST /calls/initiate` - Anruf starten
|
||||
- `GET /calls/{id}/status` - Call-Status
|
||||
- `GET /calls/{id}/recording` - Aufzeichnung abrufen
|
||||
- `POST /webhook` - Webhook-Konfiguration (eingehend)
|
||||
|
||||
**Webhooks** (Inbound von 3CX):
|
||||
- `call.started` - Anruf beginnt
|
||||
- `call.ended` - Anruf beendet
|
||||
- `call.transferred` - Anruf weitergeleitet
|
||||
|
||||
### Vermieterhelden
|
||||
|
||||
**Integration**: Webhook Sender (Lead-Eingang)
|
||||
**Base**: WordPress mit Custom Plugins
|
||||
**Format**: JSON POST zu Motia
|
||||
|
||||
**Webhook-Events**:
|
||||
- `lead.created` - Neuer Lead
|
||||
- `contact.submitted` - Kontaktformular
|
||||
lock_key = f'calendar_sync:lock:{kuerzel}'
|
||||
if not redis.set(lock_key, '1', nx=True, ex=300):
|
||||
raise LockError("Already locked")
|
||||
|
||||
# Always release
|
||||
redis.delete(lock_key)
|
||||
```
|
||||
|
||||
**Deduplication**:
|
||||
```python
|
||||
# Check & Add atomically
|
||||
existing = redis.smembers('vmh:beteiligte:create_pending')
|
||||
new_ids = input_ids - existing
|
||||
if new_ids:
|
||||
redis.sadd('vmh:beteiligte:create_pending', *new_ids)
|
||||
```
|
||||
|
||||
## Service Layer
|
||||
|
||||
### AdvowareAPI Service
|
||||
|
||||
**Location**: `services/advoware.py`
|
||||
|
||||
**Responsibilities**:
|
||||
- HMAC-512 Authentication
|
||||
- Token Management
|
||||
- HTTP Client (aiohttp)
|
||||
- Error Handling & Retries
|
||||
|
||||
**Key Methods**:
|
||||
```python
|
||||
get_access_token(force_refresh=False) -> str
|
||||
api_call(endpoint, method, params, json_data) -> Any
|
||||
```
|
||||
|
||||
**Authentication Flow**:
|
||||
```
|
||||
1. Generate HMAC-512 signature
|
||||
- Message: "{product_id}:{app_id}:{nonce}:{timestamp}"
|
||||
- Key: Base64-decoded API Key
|
||||
- Hash: SHA512
|
||||
|
||||
2. POST to security.advo-net.net/api/v1/Token
|
||||
- Body: {AppID, User, Password, HMAC512Signature, ...}
|
||||
|
||||
3. Extract access_token from response
|
||||
|
||||
4. Cache in Redis (53min TTL)
|
||||
|
||||
5. Use as Bearer Token: "Authorization: Bearer {token}"
|
||||
```
|
||||
|
||||
## External API Integration
|
||||
|
||||
### Advoware API
|
||||
|
||||
**Base URL**: `https://www2.advo-net.net:90/`
|
||||
**Auth**: HMAC-512 + Bearer Token
|
||||
**Rate Limits**: Unknown (robust error handling)
|
||||
|
||||
**Key Endpoints**:
|
||||
- `/employees` - Mitarbeiter-Liste
|
||||
- `/appointments` - Termine
|
||||
|
||||
### Google Calendar API
|
||||
|
||||
**Auth**: Service Account (JSON Key)
|
||||
**Rate Limits**: 600 requests/minute (enforced via Redis)
|
||||
**Scopes**: `https://www.googleapis.com/auth/calendar`
|
||||
|
||||
**Key Operations**:
|
||||
- `calendars().get()` - Calendar abrufen
|
||||
- `calendars().insert()` - Calendar erstellen
|
||||
- `events().list()` - Events abrufen
|
||||
- `events().insert()` - Event erstellen
|
||||
- KONG Gateway**: API-Key oder JWT-based Auth für externe Clients
|
||||
**Advoware**: User-based Auth (ADVOWARE_USER + PASSWORD)
|
||||
**Google**: Service Account (domain-wide delegation)
|
||||
**3CX**: API Key oder Basic Auth
|
||||
**Redis**: Localhost only (no password)
|
||||
**Vermieterhelden**: Webhook-Secret für Validation
|
||||
### EspoCRM
|
||||
|
||||
**Integration**: Webhook Sender (Outbound)
|
||||
**Endpoints**: Configured in EspoCRM
|
||||
**Format**: JSON POST with entity data
|
||||
|
||||
## Security
|
||||
|
||||
### Secrets Management
|
||||
|
||||
**Environment Variables**:
|
||||
```bash
|
||||
ADVOWARE_API_KEY # Base64-encoded HMAC Key
|
||||
ADVOWARE_PASSWORD # User Password
|
||||
GOOGLE_CALENDAR_SERVICE_ACCOUNT_PATH # Path to JSON Key
|
||||
ESPOCRM_MARVIN_API_KEY # Webhook Validation (optional)
|
||||
```
|
||||
|
||||
**Storage**:
|
||||
- Environment variables in systemd service
|
||||
- Service Account JSON: `/opt/motia-app/service-account.json` (chmod 600)
|
||||
- No secrets in code or Git
|
||||
|
||||
### Access Control
|
||||
|
||||
**Advoware**: User-based Auth (ADVOWARE_USER + PASSWORD)
|
||||
**Google**: Service Account (domain-wide delegation)
|
||||
**Redis**: Localhost only (no password)
|
||||
|
||||
## Performance Characteristics
|
||||
|
||||
### Throughput
|
||||
|
||||
**Calendar Sync**:
|
||||
- ~10 employees: 2-3 minutes
|
||||
- Rate-limited by Google API (600 req/min)
|
||||
- Per-employee parallelization: Nein (sequential via events)
|
||||
|
||||
**Webhooks**:
|
||||
- Instant processing (<100ms)
|
||||
- Batch support (multiple entities per request)
|
||||
- Redis dedup overhead: <10ms
|
||||
|
||||
### Memory Usage
|
||||
|
||||
**Current**: 169MB (Peak: 276MB)
|
||||
**Breakdown**:
|
||||
- Node.js process: ~150MB
|
||||
- Python dependencies: Lazy-loaded per step
|
||||
- Redis memory: <10MB
|
||||
|
||||
### Scalability
|
||||
|
||||
**Horizontal**: Nicht ohne weiteres möglich (Redis Locks, Shared State)
|
||||
**Vertical**: CPU-bound bei vielen parallel Employees
|
||||
**Bottleneck**: Google Calendar API Rate Limits
|
||||
|
||||
## Monitoring & Observability
|
||||
|
||||
### Logging
|
||||
|
||||
**Framework**: Motia Workbench (structured logging)
|
||||
**Levels**: DEBUG, INFO, ERROR
|
||||
**Output**: journalctl (systemd) + Motia Workbench UI
|
||||
|
||||
**Key Log Points**:
|
||||
- API-Requests (Method, URL, Status)
|
||||
- Event Emission (Topic, Payload)
|
||||
- Redis Operations (Keys, Success/Failure)
|
||||
- Errors (Stack traces, Context)
|
||||
|
||||
### Metrics
|
||||
|
||||
**Available** (via Logs):
|
||||
- Webhook receive count
|
||||
- Calendar sync duration per employee
|
||||
- API call count & latency
|
||||
- Redis hit/miss ratio (implicit)
|
||||
|
||||
**Missing** (Future):
|
||||
- Prometheus metrics
|
||||
- Grafana dashboards
|
||||
- Alerting
|
||||
|
||||
## Deployment
|
||||
|
||||
### systemd Service
|
||||
|
||||
**Unit**: `motia.service`
|
||||
**User**: `www-data`
|
||||
**WorkingDirectory**: `/opt/motia-app/bitbylaw`
|
||||
**Restart**: `always` (10s delay)
|
||||
|
||||
**Environment**:
|
||||
```bash
|
||||
NODE_ENV=production
|
||||
NODE_OPTIONS=--max-old-space-size=8192 --inspect
|
||||
HOST=0.0.0.0
|
||||
MOTIA_LOG_LEVEL=debug
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
**Runtime**:
|
||||
- Node.js 18+
|
||||
- Python 3.13+
|
||||
- Redis Server
|
||||
- systemd
|
||||
|
||||
**Build**:
|
||||
- npm (Node packages)
|
||||
- pip (Python packages)
|
||||
- Motia CLI
|
||||
|
||||
## Disaster Recovery
|
||||
|
||||
### Backup Strategy
|
||||
|
||||
**Redis**:
|
||||
- RDB snapshots (automatisch)
|
||||
- AOF persistence (optional)
|
||||
|
||||
**Configuration**:
|
||||
- Git-versioniert
|
||||
- Environment Variables in systemd
|
||||
|
||||
**Service Account**:
|
||||
- Manual backup: `/opt/motia-app/service-account.json`
|
||||
|
||||
### Recovery Procedures
|
||||
|
||||
**Service Restart**:
|
||||
```bash
|
||||
systemctl restart motia.service
|
||||
```
|
||||
|
||||
**Clear Redis Cache**:
|
||||
```bash
|
||||
redis-cli -n 1 FLUSHDB # Advoware Cache
|
||||
redis-cli -n 2 FLUSHDB # Calendar Sync
|
||||
```
|
||||
|
||||
**Clear Employee Lock**:
|
||||
```bash
|
||||
python /opt/motia-app/bitbylaw/delete_employee_locks.py
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### P3CX Full Integration**: Complete call handling, CTI features
|
||||
3. **Vermieterhelden Lead Processing**: Automated lead routing and enrichment
|
||||
4. **Horizontal Scaling**: Distributed locking (Redis Cluster)
|
||||
5. **Metrics & Monitoring**: Prometheus exporters
|
||||
6. **Health Checks**: `/health` endpoint via KONG
|
||||
|
||||
### Considered
|
||||
|
||||
1. **PostgreSQL Hub**: Persistent sync state (currently Redis-only)
|
||||
2. **Webhook Signatures**: Validation von Vermieterhelden/3CX requests
|
||||
3. **Multi-Tenant**: Support für mehrere Kanzleien
|
||||
4. **KONG Plugins**: Custom plugins für business logic
|
||||
1. **PostgreSQL Hub**: Persistent sync state (currently Redis-only)
|
||||
2. **Webhook Signatures**: Validation von EspoCRM requests
|
||||
3. **Multi-Tenant**: Support für mehrere Kanzleien
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Development Guide](DEVELOPMENT.md)
|
||||
- [API Reference](API.md)
|
||||
- [Configuration](CONFIGURATION.md)
|
||||
- [Troubleshooting](TROUBLESHOOTING.md)
|
||||
- [Deployment Guide](DEPLOYMENT.md)
|
||||
Reference in New Issue
Block a user