This commit is contained in:
2026-02-07 09:23:49 +00:00
parent 96eabe3db6
commit 36552903e7
85 changed files with 9820870 additions and 1767 deletions

View File

@@ -1,277 +1,206 @@
# Motia Advoware-EspoCRM Integration
# bitbylaw - Motia Integration Platform
Dieses Projekt implementiert eine robuste Integration zwischen Advoware und EspoCRM über das Motia-Framework. Es bietet eine vollständige API-Proxy für Advoware und Webhook-Handler für EspoCRM, um Änderungen an Beteiligte-Entitäten zu synchronisieren.
Event-driven Integration zwischen Advoware, EspoCRM und Google Calendar über das Motia-Framework.
## Übersicht
## Quick Start
Das System besteht aus drei Hauptkomponenten:
```bash
cd /opt/motia-app/bitbylaw
npm install
pip install -r requirements.txt
npm start
```
1. **Advoware API Proxy**: Vollständige REST-API-Proxy für alle HTTP-Methoden (GET, POST, PUT, DELETE)
2. **EspoCRM Webhook Receiver**: Empfängt Webhooks für CRUD-Operationen auf Beteiligte-Entitäten
3. **Event-Driven Sync**: Verarbeitet Synchronisationsereignisse mit Redis-basierter Deduplikation
Siehe: [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) für Details.
## Komponenten
1. **Advoware API Proxy** - REST-API-Proxy mit HMAC-512 Auth ([Details](steps/advoware_proxy/README.md))
2. **Calendar Sync** - Bidirektionale Synchronisation Advoware ↔ Google ([Details](steps/advoware_cal_sync/README.md))
3. **VMH Webhooks** - EspoCRM Webhook-Receiver für Beteiligte ([Details](steps/vmh/README.md))
## Architektur
### Komponenten
- **Motia Framework**: Event-driven Backend-Orchestrierung
- **Python Steps**: Asynchrone Verarbeitung mit aiohttp und redis-py
- **Advoware API Client**: Authentifizierte API-Kommunikation mit Token-Management
- **Redis**: Deduplikation von Webhook-Events und Caching
- **EspoCRM Integration**: Webhook-Handler für create/update/delete Operationen
### Datenfluss
```
EspoCRM Webhook → VMH Webhook Receiver → Redis Deduplication → Event Emission → Sync Handler
Advoware API → Proxy Steps → Response
┌─────────────┐ ┌──────────┐ ┌────────────┐
│ EspoCRM │────▶│ Webhooks │────▶│ Redis │
└─────────────┘ └──────────┘ │ Dedup │
└────────────┘
┌─────────────┐ ┌──────────┐ │
│ Clients │────▶│ Proxy │────▶ │
└─────────────┘ └──────────┘ │
┌────────────┐
│ Sync │
│ Handlers │
└────────────┘
┌────────────┐
│ Advoware │
│ Google │
└────────────┘
```
## Setup
Siehe: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
### Voraussetzungen
## API Endpoints
- Python 3.13+
- Node.js 18+
- Redis Server
- Motia CLI
**Advoware Proxy**:
- `GET/POST/PUT/DELETE /advoware/proxy?endpoint=...`
### Installation
**Calendar Sync**:
- `POST /advoware/calendar/sync` - Manual trigger
1. **Repository klonen und Dependencies installieren:**
```bash
cd /opt/motia-app/bitbylaw
npm install
pip install -r requirements.txt
```
**VMH Webhooks**:
- `POST /vmh/webhook/beteiligte/create`
- `POST /vmh/webhook/beteiligte/update`
- `POST /vmh/webhook/beteiligte/delete`
2. **Umgebungsvariablen konfigurieren:**
Erstellen Sie eine `.env`-Datei mit folgenden Variablen:
```env
ADVOWARE_BASE_URL=https://api.advoware.com
ADVOWARE_USERNAME=your_username
ADVOWARE_PASSWORD=your_password
REDIS_URL=redis://localhost:6379
ESPOCRM_WEBHOOK_SECRET=your_webhook_secret
```
Siehe: [docs/API.md](docs/API.md)
3. **Redis starten:**
```bash
redis-server
```
## Configuration
4. **Motia starten:**
```bash
motia start
```
Environment Variables via `.env` oder systemd service:
## Verwendung
### Advoware API Proxy
Die Proxy-Endpunkte spiegeln die Advoware-API wider:
- `GET /api/advoware/*` - Daten abrufen
- `POST /api/advoware/*` - Neue Ressourcen erstellen
- `PUT /api/advoware/*` - Ressourcen aktualisieren
- `DELETE /api/advoware/*` - Ressourcen löschen
**Beispiel:**
```bash
curl -X GET "http://localhost:3000/api/advoware/employees"
# Advoware
ADVOWARE_API_BASE_URL=https://www2.advo-net.net:90/
ADVOWARE_API_KEY=your_base64_key
ADVOWARE_USER=api_user
ADVOWARE_PASSWORD=your_password
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
# Google Calendar
GOOGLE_CALENDAR_SERVICE_ACCOUNT_PATH=/opt/motia-app/service-account.json
```
Für detaillierte Informationen zu den Proxy-Steps siehe [steps/advoware_proxy/README.md](steps/advoware_proxy/README.md).
### EspoCRM Webhooks
Webhooks werden automatisch von EspoCRM gesendet für Änderungen an Beteiligte-Entitäten:
- **Create**: `/webhooks/vmh/beteiligte/create`
- **Update**: `/webhooks/vmh/beteiligte/update`
- **Delete**: `/webhooks/vmh/beteiligte/delete`
Für detaillierte Informationen zu den Webhook- und Sync-Steps siehe [steps/vmh/README.md](steps/vmh/README.md).
### Synchronisation
Die Synchronisation läuft event-driven ab:
1. Webhook-Events werden in Redis-Queues dedupliziert
2. Events werden an den Sync-Handler emittiert
3. Sync-Handler verarbeitet die Änderungen (aktuell Placeholder)
## Konfiguration
### Motia Workbench
Die Flows sind in `motia-workbench.json` definiert:
- `advoware-proxy`: API-Proxy-Flows
- `vmh-webhook`: Webhook-Receiver-Flows
- `beteiligte-sync`: Synchronisations-Flow
### Redis Keys
- `vmh:webhook:create`: Create-Event Queue
- `vmh:webhook:update`: Update-Event Queue
- `vmh:webhook:delete`: Delete-Event Queue
## Entwicklung
### Projektstruktur
```
bitbylaw/
├── steps/
│ ├── advoware_proxy/ # API Proxy Steps - siehe [README](steps/advoware_proxy/README.md)
│ │ ├── advoware_api_proxy_get_step.py
│ │ ├── advoware_api_proxy_post_step.py
│ │ ├── advoware_api_proxy_put_step.py
│ │ └── advoware_api_proxy_delete_step.py
│ └── vmh/ # VMH Webhook & Sync Steps - siehe [README](steps/vmh/README.md)
│ ├── webhook/ # Webhook Receiver Steps
│ │ ├── beteiligte_create_api_step.py
│ │ ├── beteiligte_update_api_step.py
│ │ └── beteiligte_delete_api_step.py
│ └── beteiligte_sync_event_step.py # Sync Handler
├── services/
│ └── advoware.py # API Client
├── config.py # Configuration
├── motia-workbench.json # Flow Definitions
├── package.json
├── requirements.txt
└── tsconfig.json
```
### Testing
**API Proxy testen:**
```bash
curl -X GET "http://localhost:3000/api/advoware/employees"
```
**Webhook simulieren:**
```bash
curl -X POST "http://localhost:3000/webhooks/vmh/beteiligte/create" \
-H "Content-Type: application/json" \
-d '{"id": "123", "name": "Test Beteiligte"}'
```
### Logging
Alle Steps enthalten detaillierte Logging-Ausgaben für Debugging:
- API-Requests/Responses
- Redis-Operationen
- Event-Emission
- Fehlerbehandlung
Siehe:
- [docs/CONFIGURATION.md](docs/CONFIGURATION.md)
- [docs/GOOGLE_SETUP.md](docs/GOOGLE_SETUP.md) - Service Account Setup
## Deployment
### Docker
```dockerfile
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 3000
CMD ["motia", "start"]
```
### Production Setup
1. Redis Cluster für Hochverfügbarkeit
2. Load Balancer für API-Endpunkte
3. Monitoring für Sync-Operationen
4. Backup-Strategie für Redis-Daten
## Fehlerbehebung
### Häufige Probleme
1. **Context Attribute Error**: Verwenden Sie `Config` statt `context.config`
2. **Redis Connection Failed**: Überprüfen Sie Redis-URL und Netzwerkverbindung
3. **Webhook Duplikate**: Redis-Deduplikation verhindert Mehrfachverarbeitung
### Logs überprüfen
Production deployment via systemd:
```bash
motia logs
sudo systemctl status motia.service
sudo journalctl -u motia.service -f
```
## Calendar Sync
Siehe: [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md)
Das System enthält auch eine bidirektionale Kalender-Synchronisation zwischen Advoware und Google Calendar.
## Documentation
### Architektur
### Getting Started
- [Development Guide](docs/DEVELOPMENT.md) - Setup, Coding Standards, Testing
- [Configuration](docs/CONFIGURATION.md) - Environment Variables
- [Deployment](docs/DEPLOYMENT.md) - Production Setup
- **PostgreSQL Hub**: Speichert Sync-Zustand und verhindert Datenverlust
- **Event-Driven Sync**: 4-Phasen-Sync (Neu, Gelöscht, Aktualisiert)
- **Safe Wrappers**: Globale Write-Protection für Advoware-Schreiboperationen
- **Rate Limiting**: Backoff-Handling für Google Calendar API-Limits
### Technical Details
- [Architecture](docs/ARCHITECTURE.md) - System Design, Datenflüsse
- [API Reference](docs/API.md) - HTTP Endpoints, Event Topics
- [Troubleshooting](docs/TROUBLESHOOTING.md) - Common Issues
### Dauertermine (Recurring Appointments)
### Components
- [Advoware Proxy](steps/advoware_proxy/README.md) - API Proxy Details
- [Calendar Sync](steps/advoware_cal_sync/README.md) - Sync Logic
- [VMH Webhooks](steps/vmh/README.md) - Webhook Handlers
- [Advoware Service](services/ADVOWARE_SERVICE.md) - API Client
Advoware verwendet `dauertermin=1` für wiederkehrende Termine mit folgenden Feldern:
### Step Documentation
Jeder Step hat eine detaillierte `.md` Dokumentation neben der `.py` Datei.
- `turnus`: Intervall (z.B. 1 = jeden, 3 = jeden 3.)
- `turnusArt`: Frequenz-Einheit
- `1` = Täglich (DAILY)
- `2` = Wöchentlich (WEEKLY)
- `3` = Monatlich (MONTHLY)
- `4` = Jährlich (YEARLY)
- `datumBis`: Enddatum der Wiederholung
## Project Structure
**RRULE-Generierung:**
```
RRULE:FREQ={FREQ};INTERVAL={turnus};UNTIL={datumBis}
bitbylaw/
├── docs/ # Documentation
├── steps/ # Motia Steps
│ ├── advoware_proxy/ # API Proxy Steps + Docs
│ ├── advoware_cal_sync/ # Calendar Sync Steps + Docs
│ └── vmh/ # Webhook Steps + Docs
├── services/ # Shared Services
│ └── advoware.py # API Client + Doc
├── config.py # Configuration Loader
├── package.json # Node.js Dependencies
└── requirements.txt # Python Dependencies
```
Beispiel: `turnus=3, turnusArt=1` → `RRULE:FREQ=DAILY;INTERVAL=3;UNTIL=20251224`
## Technology Stack
### Setup
- **Framework**: Motia v0.8.2-beta.139 (Event-Driven Backend)
- **Languages**: Python 3.13, Node.js 18, TypeScript
- **Data Store**: Redis (Caching, Locking, Deduplication)
- **External APIs**: Advoware REST API, Google Calendar API, EspoCRM
1. **Google Service Account**: `service-account.json` im Projektroot
2. **Umgebungsvariablen**:
```env
ADVOWARE_WRITE_PROTECTION=false # Global write protection
POSTGRES_HOST=localhost
GOOGLE_CALENDAR_SERVICE_ACCOUNT_PATH=service-account.json
```
3. **Trigger Sync**:
```bash
curl -X POST "http://localhost:3000/advoware/calendar/sync" -H "Content-Type: application/json" -d '{"full_content": true}'
```
## Development
### Rate Limiting & Backoff
```bash
# Development mode
npm run dev
- **Google Calendar API**: 403-Fehler bei Rate-Limits werden mit exponentiellem Backoff (max. 60s) wiederholt
- **Globales Rate Limiting**: 600 Anfragen/Minute über alle parallel laufenden Sync-Prozesse hinweg mittels Redis Sorted Set
- **Gleitendes Fenster**: 60-Sekunden-Fenster für kontinuierliche Überwachung des Durchschnitts
- **Delays**: 100ms zwischen API-Calls zur Vermeidung von Limits
- **Retry-Logic**: Max. 4 Versuche mit base=4
# Generate types
npm run generate-types
### Sicherheit
# Clean build
npm run clean && npm install
```
- **Write Protection**: `ADVOWARE_WRITE_PROTECTION=true` deaktiviert alle Advoware-Schreiboperationen
- **Per-User Calendars**: Automatische Erstellung und Freigabe von Google-Calendars pro Mitarbeiter
---
### Troubleshooting
## Projektstruktur
- **Rate Limit Errors**: Logs zeigen Backoff-Retries; warten oder Limits erhöhen
- **Sync Failures**: `ADVOWARE_WRITE_PROTECTION=false` setzen für Debugging
- **Calendar Access**: Service Account muss Owner-Rechte haben
```
bitbylaw/
├── docs/ # Comprehensive documentation
│ ├── advoware/ # Advoware API documentation (Swagger)
│ └── *.md # Architecture, Development, Configuration, etc.
├── scripts/ # Utility scripts for maintenance
│ └── calendar_sync/ # Calendar sync helper scripts
├── services/ # Shared service implementations
├── steps/ # Motia step implementations
│ ├── advoware_proxy/ # REST API proxy steps
│ ├── advoware_cal_sync/ # Calendar synchronization steps
│ └── vmh/ # EspoCRM webhook handlers
├── src/ # TypeScript sources (unused currently)
└── config.py # Central configuration
```
## Lizenz
**Key Files**:
- [docs/INDEX.md](docs/INDEX.md) - Documentation navigation
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) - System architecture
- [docs/advoware/advoware_api_swagger.json](docs/advoware/advoware_api_swagger.json) - Advoware API spec
- [scripts/calendar_sync/README.md](scripts/calendar_sync/README.md) - Utility scripts
[License Information]
---
## Beitrag
## Testing
Bitte erstellen Sie Issues für Bugs oder Feature-Requests. Pull-Requests sind willkommen!
```bash
# Test Advoware Proxy
curl -X GET "http://localhost:3000/advoware/proxy?endpoint=employees"
# Test Calendar Sync
curl -X POST "http://localhost:3000/advoware/calendar/sync" \
-H "Content-Type: application/json" \
-d '{"full_content": true}'
# Test Webhook
curl -X POST "http://localhost:3000/vmh/webhook/beteiligte/create" \
-H "Content-Type: application/json" \
-d '[{"id": "test-123"}]'
```
## License
[Your License]
## Support
- **Issues**: [GitHub Issues]
- **Docs**: [docs/](docs/)
- **Logs**: `sudo journalctl -u motia.service -f`