Update README and add detailed documentation for Advoware integration and calendar sync
This commit is contained in:
268
steps/advoware_cal_sync/README.md
Normal file
268
steps/advoware_cal_sync/README.md
Normal file
@@ -0,0 +1,268 @@
|
||||
# Advoware Calendar Sync - Event-Driven Design
|
||||
|
||||
Dieser Abschnitt implementiert die bidirektionale Synchronisation zwischen Advoware-Terminen und Google Calendar. Das System nutzt einen event-driven Ansatz mit **Motia III v1.0-RC**, der auf direkten API-Calls basiert, mit Redis für Locking und Deduplikation. Es stellt sicher, dass Termine konsistent gehalten werden, mit Fokus auf Robustheit, Fehlerbehandlung und korrekte Handhabung von mehrtägigen Terminen.
|
||||
|
||||
## Übersicht
|
||||
|
||||
Das System synchronisiert Termine zwischen:
|
||||
- **Advoware**: Zentrale Terminverwaltung mit detaillierten Informationen.
|
||||
- **Google Calendar**: Benutzerfreundliche Kalenderansicht für jeden Mitarbeiter.
|
||||
|
||||
## Architektur
|
||||
|
||||
### Event-Driven Design
|
||||
- **Direkte API-Synchronisation**: Kein zentraler Hub; Sync läuft direkt zwischen APIs.
|
||||
- **Redis Locking**: Per-Employee Locking verhindert Race-Conditions.
|
||||
- **Event Emission**: Cron → All-Step → Employee-Step für skalierbare Verarbeitung.
|
||||
- **Fehlerresistenz**: Einzelne Fehler stoppen nicht den gesamten Sync.
|
||||
- **Logging**: Alle Logs erscheinen in der iii Console via `ctx.logger`.
|
||||
|
||||
### Sync-Phasen
|
||||
1. **Cron-Step**: Automatische Auslösung alle 15 Minuten.
|
||||
2. **All-Step**: Fetcht alle Mitarbeiter und emittiert Events pro Employee.
|
||||
3. **Employee-Step**: Synchronisiert Termine für einen einzelnen Mitarbeiter.
|
||||
|
||||
### Datenmapping und Standardisierung
|
||||
Beide Systeme werden auf gemeinsames Format normalisiert (Berlin TZ):
|
||||
```python
|
||||
{
|
||||
'start': datetime, # Berlin TZ
|
||||
'end': datetime,
|
||||
'text': str,
|
||||
'notiz': str,
|
||||
'ort': str,
|
||||
'dauertermin': int, # 0/1
|
||||
'turnus': int, # 0/1
|
||||
'turnusArt': int,
|
||||
'recurrence': str # RRULE oder None
|
||||
}
|
||||
```
|
||||
|
||||
#### Advoware → Standard
|
||||
- Start: `datum` + `uhrzeitVon` (Fallback 09:00), oder `datum` als datetime.
|
||||
- End: `datumBis` + `uhrzeitBis` (Fallback 10:00), oder `datum` + 1h.
|
||||
- All-Day: `dauertermin=1` oder Dauer >1 Tag.
|
||||
- Recurring: `turnus`/`turnusArt` (vereinfacht, keine RRULE).
|
||||
|
||||
#### Google → Standard
|
||||
- Start/End: `dateTime` oder `date` (All-Day).
|
||||
- All-Day: `dauertermin=1` wenn All-Day oder Dauer >1 Tag.
|
||||
- Recurring: RRULE aus `recurrence`.
|
||||
|
||||
#### Standard → Advoware
|
||||
- POST/PUT: `datum`/`uhrzeitBis`/`datumBis` aus start/end.
|
||||
- Defaults: `vorbereitungsDauer='00:00:00'`, `sb`/`anwalt`=employee_kuerzel.
|
||||
|
||||
#### Standard → Google
|
||||
- All-Day: `date` statt `dateTime`, end +1 Tag.
|
||||
- Recurring: RRULE aus `recurrence`.
|
||||
|
||||
## Funktionalität
|
||||
|
||||
### Automatische Kalender-Erstellung
|
||||
- Für jeden Advoware-Mitarbeiter wird ein Google Calendar mit dem Namen `AW-{Kuerzel}` erstellt.
|
||||
- Beispiel: Mitarbeiter mit Kürzel "SB" → Calendar "AW-SB".
|
||||
- Kalender wird mit dem Haupt-Google-Account (`lehmannundpartner@gmail.com`) als Owner geteilt.
|
||||
|
||||
### Sync-Details
|
||||
|
||||
#### Cron-Step (calendar_sync_cron_step.py)
|
||||
- Läuft alle 15 Minuten und emittiert "calendar_sync_all".
|
||||
- **Trigger**: `cron("0 */15 * * * *")` (6-field: Sekunde Minute Stunde Tag Monat Wochentag)
|
||||
|
||||
#### All-Step (calendar_sync_all_step.py)
|
||||
- Fetcht alle Mitarbeiter aus Advoware.
|
||||
- Filtert Debug-Liste (falls konfiguriert).
|
||||
- Setzt Redis-Lock pro Employee.
|
||||
- Emittiert "calendar_sync" Event pro Employee.
|
||||
- **Trigger**: `queue('calendar_sync_all')`
|
||||
|
||||
#### Employee-Step (calendar_sync_event_step.py)
|
||||
- Fetcht Advoware-Termine für den Employee.
|
||||
- Fetcht Google-Events für den Employee.
|
||||
- Synchronisiert: Neue erstellen, Updates anwenden, Deletes handhaben.
|
||||
- Verwendet Locking, um parallele Syncs zu verhindern.
|
||||
- **Trigger**: `queue('calendar_sync')`
|
||||
|
||||
#### API-Step (calendar_sync_api_step.py)
|
||||
- Manueller Trigger für einzelnen Employee oder "ALL".
|
||||
- Bei "ALL": Emittiert "calendar_sync_all".
|
||||
- Bei Employee: Setzt Lock und emittiert "calendar_sync".
|
||||
- **Trigger**: `http('POST', '/advoware/calendar/sync')`
|
||||
|
||||
## API-Schwächen und Fixes
|
||||
|
||||
### Advoware API
|
||||
- **Mehrtägige Termine**: `datumBis` wird korrekt für Enddatum verwendet; '00:00:00' als '23:59:59' interpretiert.
|
||||
- **Zeitformate**: Robuste Parsing mit Fallbacks.
|
||||
- **Keine 24h-Limit**: Termine können länger als 24h sein; Google Calendar unterstützt das.
|
||||
|
||||
### Google Calendar API
|
||||
- **Zeitbereiche**: Akzeptiert Events >24h ohne Probleme.
|
||||
- **Rate Limits**: Backoff-Retry implementiert.
|
||||
|
||||
## Step-Konfiguration (Motia III)
|
||||
|
||||
### calendar_sync_cron_step.py
|
||||
```python
|
||||
config = {
|
||||
'name': 'Calendar Sync Cron Job',
|
||||
'flows': ['advoware'],
|
||||
'triggers': [
|
||||
cron("0 */15 * * * *") # Alle 15 Minuten (6-field format)
|
||||
],
|
||||
'enqueues': ['calendar_sync_all']
|
||||
}
|
||||
```
|
||||
|
||||
### calendar_sync_all_step.py
|
||||
```python
|
||||
config = {
|
||||
'name': 'Calendar Sync All Step',
|
||||
'flows': ['advoware'],
|
||||
'triggers': [
|
||||
queue('calendar_sync_all')
|
||||
],
|
||||
'enqueues': ['calendar_sync']
|
||||
}
|
||||
```
|
||||
|
||||
### calendar_sync_event_step.py
|
||||
```python
|
||||
config = {
|
||||
'name': 'Calendar Sync Event Step',
|
||||
'flows': ['advoware'],
|
||||
'triggers': [
|
||||
queue('calendar_sync')
|
||||
],
|
||||
'enqueues': []
|
||||
}
|
||||
```
|
||||
|
||||
### calendar_sync_api_step.py
|
||||
```python
|
||||
config = {
|
||||
'name': 'Calendar Sync API Trigger',
|
||||
'flows': ['advoware'],
|
||||
'triggers': [
|
||||
http('POST', '/advoware/calendar/sync')
|
||||
],
|
||||
'enqueues': ['calendar_sync', 'calendar_sync_all']
|
||||
}
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
### Umgebungsvariablen
|
||||
```env
|
||||
# Google Calendar
|
||||
GOOGLE_CALENDAR_SERVICE_ACCOUNT_PATH=service-account.json
|
||||
|
||||
# Advoware API
|
||||
ADVOWARE_API_BASE_URL=https://www2.advo-net.net:90/
|
||||
ADVOWARE_PRODUCT_ID=64
|
||||
ADVOWARE_APP_ID=your_app_id
|
||||
ADVOWARE_API_KEY=your_api_key
|
||||
ADVOWARE_KANZLEI=your_kanzlei
|
||||
ADVOWARE_DATABASE=your_database
|
||||
ADVOWARE_USER=your_user
|
||||
ADVOWARE_ROLE=2
|
||||
ADVOWARE_PASSWORD=your_password
|
||||
ADVOWARE_TOKEN_LIFETIME_MINUTES=55
|
||||
ADVOWARE_API_TIMEOUT_SECONDS=30
|
||||
|
||||
# Redis
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_DB_CALENDAR_SYNC=1
|
||||
REDIS_TIMEOUT_SECONDS=5
|
||||
|
||||
# Debug
|
||||
CALENDAR_SYNC_DEBUG_EMPLOYEES=PB,AI # Optional, filter employees
|
||||
```
|
||||
|
||||
## Verwendung
|
||||
|
||||
### Manueller Sync
|
||||
```bash
|
||||
# Sync für einen bestimmten Mitarbeiter
|
||||
curl -X POST "http://localhost:3111/advoware/calendar/sync" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"kuerzel": "PB"}'
|
||||
|
||||
# Sync für alle Mitarbeiter
|
||||
curl -X POST "http://localhost:3111/advoware/calendar/sync" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"kuerzel": "ALL"}'
|
||||
```
|
||||
|
||||
### Automatischer Sync
|
||||
Cron-Step läuft automatisch alle 15 Minuten.
|
||||
|
||||
## Fehlerbehandlung und Logging
|
||||
|
||||
- **Locking**: Redis NX/EX verhindert parallele Syncs.
|
||||
- **Logging**: `ctx.logger` für iii Console-Sichtbarkeit.
|
||||
- **API-Fehler**: Retry mit Backoff.
|
||||
- **Parsing-Fehler**: Robuste Fallbacks.
|
||||
|
||||
## Sicherheit
|
||||
|
||||
- Service Account für Google Calendar API.
|
||||
- HMAC-512 Authentifizierung für Advoware API.
|
||||
- Redis für Concurrency-Control.
|
||||
|
||||
## Bekannte Probleme
|
||||
|
||||
- **Recurring-Events**: Begrenzte Unterstützung für komplexe Wiederholungen.
|
||||
- **Performance**: Bei vielen Terminen Paginierung beachten.
|
||||
- **Timezone-Handling**: Alle Operationen in Europe/Berlin TZ.
|
||||
|
||||
## Datenfluss
|
||||
|
||||
```
|
||||
Cron (alle 15min)
|
||||
→ calendar_sync_cron_step
|
||||
→ ctx.enqueue(topic: "calendar_sync_all")
|
||||
→ calendar_sync_all_step
|
||||
→ Fetch Employees from Advoware
|
||||
→ For each Employee:
|
||||
→ Set Redis Lock (key: calendar_sync:employee:{kuerzel})
|
||||
→ ctx.enqueue(topic: "calendar_sync", data: {kuerzel, ...})
|
||||
→ calendar_sync_event_step
|
||||
→ Fetch Advoware Termine (frNr, datum, text, etc.)
|
||||
→ Fetch Google Calendar Events
|
||||
→ 4-Phase Sync:
|
||||
1. New from Advoware → Google
|
||||
2. New from Google → Advoware
|
||||
3. Process Deletes
|
||||
4. Process Updates
|
||||
→ Clear Redis Lock
|
||||
```
|
||||
|
||||
## Weitere Dokumentation
|
||||
|
||||
- **Individual Step Docs**: Siehe `docs/` Ordner in diesem Verzeichnis
|
||||
- **Architecture Overview**: [../../docs/ARCHITECTURE.md](../../docs/ARCHITECTURE.md)
|
||||
- **Google Setup Guide**: [../../docs/GOOGLE_SETUP.md](../../docs/GOOGLE_SETUP.md)
|
||||
- **Troubleshooting**: [../../docs/TROUBLESHOOTING.md](../../docs/TROUBLESHOOTING.md)
|
||||
|
||||
## Migration Notes
|
||||
|
||||
Dieses System wurde von **Motia v0.17** nach **Motia III v1.0-RC** migriert:
|
||||
|
||||
### Wichtige Änderungen:
|
||||
- ✅ `type: 'event'` → `triggers: [queue('topic')]`
|
||||
- ✅ `type: 'cron'` → `triggers: [cron('expression')]` (6-field format)
|
||||
- ✅ `type: 'api'` → `triggers: [http('METHOD', 'path')]`
|
||||
- ✅ `context.emit()` → `ctx.enqueue()`
|
||||
- ✅ `emits: [...]` → `enqueues: [...]`
|
||||
- ✅ Relative Imports → Absolute Imports mit `sys.path.insert()`
|
||||
- ✅ Motia Workbench → iii Console
|
||||
|
||||
### Kompatibilität:
|
||||
- ✅ Alle 4 Steps vollständig migriert
|
||||
- ✅ Google Calendar API Integration unverändert
|
||||
- ✅ Advoware API Integration unverändert
|
||||
- ✅ Redis Locking-Mechanismus unverändert
|
||||
- ✅ Datenbank-Schema kompatibel
|
||||
314
steps/advoware_proxy/README.md
Normal file
314
steps/advoware_proxy/README.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# Advoware API Proxy Steps
|
||||
|
||||
Dieser Ordner enthält die API-Proxy-Steps für die Advoware-Integration. Jeder Step implementiert eine HTTP-Methode als universellen Proxy zur Advoware-API mit **Motia III v1.0-RC**.
|
||||
|
||||
## Übersicht
|
||||
|
||||
Die Proxy-Steps fungieren als transparente Schnittstelle zwischen Clients und der Advoware-API. Sie handhaben Authentifizierung, Fehlerbehandlung und Logging automatisch.
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. GET Proxy (`advoware_api_proxy_get_step.py`)
|
||||
|
||||
**Zweck:** Universeller Proxy für GET-Requests an die Advoware-API.
|
||||
|
||||
**Konfiguration:**
|
||||
```python
|
||||
config = {
|
||||
'name': 'Advoware Proxy GET',
|
||||
'flows': ['advoware'],
|
||||
'triggers': [
|
||||
http('GET', '/advoware/proxy')
|
||||
],
|
||||
'enqueues': []
|
||||
}
|
||||
```
|
||||
|
||||
**Funktionalität:**
|
||||
- Extrahiert den Ziel-Endpoint aus Query-Parametern (`endpoint`)
|
||||
- Übergibt alle anderen Query-Parameter als API-Parameter
|
||||
- Gibt das Ergebnis als JSON zurück
|
||||
|
||||
**Beispiel Request:**
|
||||
```bash
|
||||
GET /advoware/proxy?endpoint=employees&limit=10&offset=0
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"result": {
|
||||
"data": [...],
|
||||
"total": 100
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. POST Proxy (`advoware_api_proxy_post_step.py`)
|
||||
|
||||
**Zweck:** Universeller Proxy für POST-Requests an die Advoware-API.
|
||||
|
||||
**Konfiguration:**
|
||||
```python
|
||||
config = {
|
||||
'name': 'Advoware Proxy POST',
|
||||
'flows': ['advoware'],
|
||||
'triggers': [
|
||||
http('POST', '/advoware/proxy')
|
||||
],
|
||||
'enqueues': []
|
||||
}
|
||||
```
|
||||
|
||||
**Funktionalität:**
|
||||
- Extrahiert den Ziel-Endpoint aus Query-Parametern (`endpoint`)
|
||||
- Verwendet den Request-Body als JSON-Daten für die API
|
||||
- Erstellt neue Ressourcen in Advoware
|
||||
|
||||
**Beispiel Request:**
|
||||
```bash
|
||||
POST /advoware/proxy?endpoint=employees
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "John Doe",
|
||||
"email": "john@example.com"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. PUT Proxy (`advoware_api_proxy_put_step.py`)
|
||||
|
||||
**Zweck:** Universeller Proxy für PUT-Requests an die Advoware-API.
|
||||
|
||||
**Konfiguration:**
|
||||
```python
|
||||
config = {
|
||||
'name': 'Advoware Proxy PUT',
|
||||
'flows': ['advoware'],
|
||||
'triggers': [
|
||||
http('PUT', '/advoware/proxy')
|
||||
],
|
||||
'enqueues': []
|
||||
}
|
||||
```
|
||||
|
||||
**Funktionalität:**
|
||||
- Extrahiert den Ziel-Endpoint aus Query-Parametern (`endpoint`)
|
||||
- Verwendet den Request-Body als JSON-Daten für Updates
|
||||
- Aktualisiert bestehende Ressourcen in Advoware
|
||||
|
||||
**Beispiel Request:**
|
||||
```bash
|
||||
PUT /advoware/proxy?endpoint=employees/123
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "John Smith",
|
||||
"email": "johnsmith@example.com"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. DELETE Proxy (`advoware_api_proxy_delete_step.py`)
|
||||
|
||||
**Zweck:** Universeller Proxy für DELETE-Requests an die Advoware-API.
|
||||
|
||||
**Konfiguration:**
|
||||
```python
|
||||
config = {
|
||||
'name': 'Advoware Proxy DELETE',
|
||||
'flows': ['advoware'],
|
||||
'triggers': [
|
||||
http('DELETE', '/advoware/proxy')
|
||||
],
|
||||
'enqueues': []
|
||||
}
|
||||
```
|
||||
|
||||
**Funktionalität:**
|
||||
- Extrahiert den Ziel-Endpoint aus Query-Parametern (`endpoint`)
|
||||
- Löscht Ressourcen in Advoware
|
||||
|
||||
**Beispiel Request:**
|
||||
```bash
|
||||
DELETE /advoware/proxy?endpoint=employees/123
|
||||
```
|
||||
|
||||
## Gemeinsame Features
|
||||
|
||||
### Authentifizierung
|
||||
Alle Steps verwenden den `AdvowareService` für automatische Token-Verwaltung und Authentifizierung:
|
||||
- HMAC-512 basierte Signatur
|
||||
- Token-Caching in Redis (55 Minuten Lifetime)
|
||||
- Automatischer Token-Refresh bei 401-Errors
|
||||
|
||||
### Fehlerbehandling
|
||||
- **400 Bad Request:** Fehlender `endpoint` Parameter
|
||||
- **500 Internal Server Error:** API-Fehler oder Exceptions
|
||||
- **401 Unauthorized:** Automatischer Token-Refresh und Retry
|
||||
|
||||
### Logging
|
||||
Detaillierte Logs via `ctx.logger` für:
|
||||
- Eingehende Requests
|
||||
- API-Calls an Advoware
|
||||
- Fehler und Exceptions
|
||||
- Token-Management
|
||||
|
||||
Alle Logs sind in der **iii Console** sichtbar.
|
||||
|
||||
### Sicherheit
|
||||
- Keine direkte Weitergabe sensibler Daten
|
||||
- Authentifizierung über Service-Layer
|
||||
- Input-Validation für erforderliche Parameter
|
||||
- HMAC-512 Signatur für alle API-Requests
|
||||
|
||||
## Handler-Struktur (Motia III)
|
||||
|
||||
Alle Steps folgen dem gleichen Pattern:
|
||||
|
||||
```python
|
||||
from motia import http, ApiRequest, ApiResponse, FlowContext
|
||||
from services.advoware_service import AdvowareService
|
||||
|
||||
config = {
|
||||
'name': 'Advoware Proxy {METHOD}',
|
||||
'flows': ['advoware'],
|
||||
'triggers': [
|
||||
http('{METHOD}', '/advoware/proxy')
|
||||
],
|
||||
'enqueues': []
|
||||
}
|
||||
|
||||
async def handler(request: ApiRequest, ctx: FlowContext) -> ApiResponse:
|
||||
# Extract endpoint from query params
|
||||
endpoint = request.query_params.get('endpoint')
|
||||
|
||||
if not endpoint:
|
||||
return ApiResponse(
|
||||
status=400,
|
||||
body={'error': 'Missing required query parameter: endpoint'}
|
||||
)
|
||||
|
||||
# Call Advoware API
|
||||
advoware_service = AdvowareService()
|
||||
result = await advoware_service.{method}(endpoint, **params)
|
||||
|
||||
return ApiResponse(status=200, body={'result': result})
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Unit Tests
|
||||
```bash
|
||||
# Test GET Proxy
|
||||
curl -X GET "http://localhost:3111/advoware/proxy?endpoint=employees"
|
||||
|
||||
# Test POST Proxy
|
||||
curl -X POST "http://localhost:3111/advoware/proxy?endpoint=employees" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "Test Employee"}'
|
||||
|
||||
# Test PUT Proxy
|
||||
curl -X PUT "http://localhost:3111/advoware/proxy?endpoint=employees/1" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "Updated Employee"}'
|
||||
|
||||
# Test DELETE Proxy
|
||||
curl -X DELETE "http://localhost:3111/advoware/proxy?endpoint=employees/1"
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
Überprüfen Sie die Logs in der iii Console:
|
||||
```bash
|
||||
# Check logs
|
||||
curl http://localhost:3111/_console/logs
|
||||
```
|
||||
|
||||
## Konfiguration
|
||||
|
||||
### Umgebungsvariablen
|
||||
Stellen Sie sicher, dass folgende Variablen gesetzt sind:
|
||||
```env
|
||||
ADVOWARE_API_BASE_URL=https://www2.advo-net.net:90/
|
||||
ADVOWARE_PRODUCT_ID=64
|
||||
ADVOWARE_APP_ID=your_app_id
|
||||
ADVOWARE_API_KEY=your_api_key
|
||||
ADVOWARE_KANZLEI=your_kanzlei
|
||||
ADVOWARE_DATABASE=your_database
|
||||
ADVOWARE_USER=your_user
|
||||
ADVOWARE_ROLE=2
|
||||
ADVOWARE_PASSWORD=your_password
|
||||
ADVOWARE_TOKEN_LIFETIME_MINUTES=55
|
||||
ADVOWARE_API_TIMEOUT_SECONDS=30
|
||||
|
||||
# Redis (für Token-Caching)
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_DB=0
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
- `services/advoware_service.py` - Advoware API Client mit HMAC Auth
|
||||
- `config.py` - Konfigurationsmanagement
|
||||
- `motia` - Motia III Python SDK
|
||||
- `asyncpg` - PostgreSQL Client
|
||||
- `redis` - Redis Client für Token-Caching
|
||||
|
||||
## Erweiterungen
|
||||
|
||||
### Geplante Features
|
||||
- Request/Response Caching für häufige Queries
|
||||
- Rate Limiting pro Client
|
||||
- Request Validation Schemas mit Pydantic
|
||||
- Batch-Operations Support
|
||||
|
||||
### Custom Endpoints
|
||||
Für spezifische Endpoints können zusätzliche Steps erstellt werden, die direkt auf bestimmte Ressourcen zugreifen und erweiterte Validierung/Transformation bieten.
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
Client Request
|
||||
│
|
||||
▼
|
||||
HTTP Trigger (http('METHOD', '/advoware/proxy'))
|
||||
│
|
||||
▼
|
||||
Handler (ApiRequest → ApiResponse)
|
||||
│
|
||||
├─► Extract 'endpoint' from query params
|
||||
├─► Extract other params/body
|
||||
│
|
||||
▼
|
||||
AdvowareService
|
||||
│
|
||||
├─► Check Redis for valid token
|
||||
├─► If expired: Get new token (HMAC-512 auth)
|
||||
├─► Build HTTP request
|
||||
│
|
||||
▼
|
||||
Advoware API
|
||||
│
|
||||
▼
|
||||
Response → Transform → Return ApiResponse
|
||||
```
|
||||
|
||||
## Migration Notes
|
||||
|
||||
Dieses System wurde von **Motia v0.17** nach **Motia III v1.0-RC** migriert:
|
||||
|
||||
### Wichtige Änderungen:
|
||||
- ✅ `type: 'api'` → `triggers: [http('METHOD', 'path')]`
|
||||
- ✅ `ApiRouteConfig` → `StepConfig` mit `as const satisfies`
|
||||
- ✅ `Handlers['StepName']` → `Handlers<typeof config>`
|
||||
- ✅ `context` → `ctx`
|
||||
- ✅ `req` dict → `ApiRequest` typed object
|
||||
- ✅ Return dict → `ApiResponse` typed object
|
||||
- ✅ `method`, `path` moved into trigger
|
||||
- ✅ Motia Workbench → iii Console
|
||||
|
||||
### Kompatibilität:
|
||||
- ✅ Alle 4 Proxy Steps vollständig migriert
|
||||
- ✅ AdvowareService kompatibel (keine Änderungen)
|
||||
- ✅ Redis Token-Caching unverändert
|
||||
- ✅ HMAC-512 Auth unverändert
|
||||
- ✅ API-Endpoints identisch
|
||||
Reference in New Issue
Block a user