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

514
bitbylaw/docs/API.md Normal file
View File

@@ -0,0 +1,514 @@
# API Reference
---
title: API Reference
description: Vollständige API-Dokumentation für bitbylaw Motia Installation
date: 2026-02-07
version: 1.1.0
---
## Base URL
**Production (via KONG)**: `https://api.bitbylaw.com`
**Development**: `http://localhost:3000`
---
## Authentication
### KONG API Gateway
Alle Produktions-API-Calls laufen über KONG mit API-Key-Authentifizierung:
```bash
curl -H "apikey: YOUR_API_KEY" https://api.bitbylaw.com/advoware/proxy?endpoint=employees
```
**Header**: `apikey: <your-api-key>`
### Development
Entwicklungs-Environment: Keine Authentifizierung auf Motia-Ebene erforderlich.
---
## Advoware Proxy API
### Universal Proxy Endpoint
Alle Advoware-API-Aufrufe laufen über einen universellen Proxy.
#### GET Request
**Endpoint**: `GET /advoware/proxy`
**Query Parameters**:
- `endpoint` (required): Advoware API endpoint (ohne Base-URL)
- Alle weiteren Parameter werden an Advoware weitergeleitet
**Example**:
```bash
curl -X GET "http://localhost:3000/advoware/proxy?endpoint=employees&limit=10"
```
**Response**:
```json
{
"status": 200,
"body": {
"result": {
"data": [...],
"total": 100
}
}
}
```
#### POST Request
**Endpoint**: `POST /advoware/proxy`
**Query Parameters**:
- `endpoint` (required): Advoware API endpoint
**Request Body**: JSON data für Advoware API
**Example**:
```bash
curl -X POST "http://localhost:3000/advoware/proxy?endpoint=appointments" \
-H "Content-Type: application/json" \
-d '{
"datum": "2026-02-10",
"uhrzeitVon": "09:00:00",
"text": "Meeting"
}'
```
**Response**:
```json
{
"status": 200,
"body": {
"result": {
"id": "12345"
}
}
}
```
#### PUT Request
**Endpoint**: `PUT /advoware/proxy`
**Query Parameters**:
- `endpoint` (required): Advoware API endpoint (inkl. ID)
**Request Body**: JSON data für Update
**Example**:
```bash
curl -X PUT "http://localhost:3000/advoware/proxy?endpoint=appointments/12345" \
-H "Content-Type: application/json" \
-d '{
"text": "Updated Meeting"
}'
```
#### DELETE Request
**Endpoint**: `DELETE /advoware/proxy`
**Query Parameters**:
- `endpoint` (required): Advoware API endpoint (inkl. ID)
**Example**:
```bash
curl -X DELETE "http://localhost:3000/advoware/proxy?endpoint=appointments/12345"
```
**Response**:
```json
{
"status": 200,
"body": {
"result": null
}
}
```
### Error Responses
**400 Bad Request**:
```json
{
"status": 400,
"body": {
"error": "Endpoint required as query param"
}
}
```
**500 Internal Server Error**:
```json
{
"status": 500,
"body": {
"error": "Internal server error",
"details": "Error message"
}
}
```
## Calendar Sync API
### Trigger Full Sync
**Endpoint**: `POST /advoware/calendar/sync`
**Request Body**:
```json
{
"kuerzel": "ALL",
"full_content": true
}
```
**Parameters**:
- `kuerzel` (optional): Mitarbeiter-Kürzel oder "ALL" (default: "ALL")
- `full_content` (optional): Volle Details vs. anonymisiert (default: true)
**Examples**:
Sync all employees:
```bash
curl -X POST "http://localhost:3000/advoware/calendar/sync" \
-H "Content-Type: application/json" \
-d '{"full_content": true}'
```
Sync single employee:
```bash
curl -X POST "http://localhost:3000/advoware/calendar/sync" \
-H "Content-Type: application/json" \
-d '{"kuerzel": "SB", "full_content": true}'
```
Sync with anonymization:
```bash
curl -X POST "http://localhost:3000/advoware/calendar/sync" \
-H "Content-Type: application/json" \
-d '{"full_content": false}'
```
**Response**:
```json
{
"status": "triggered",
"kuerzel": "ALL",
"message": "Calendar sync triggered for ALL"
}
```
**Status Codes**:
- `200`: Sync triggered successfully
- `400`: Invalid request (z.B. lock aktiv)
- `500`: Internal error
## VMH Webhook Endpoints
Diese Endpoints werden von EspoCRM aufgerufen.
### Beteiligte Create Webhook
**Endpoint**: `POST /vmh/webhook/beteiligte/create`
**Request Body**: Array von Entitäten
```json
[
{
"id": "entity-123",
"name": "Max Mustermann",
"createdAt": "2026-02-07T10:00:00Z"
}
]
```
**Response**:
```json
{
"status": "received",
"action": "create",
"new_ids_count": 1,
"total_ids_in_batch": 1
}
```
### Beteiligte Update Webhook
**Endpoint**: `POST /vmh/webhook/beteiligte/update`
**Request Body**: Array von Entitäten
```json
[
{
"id": "entity-123",
"name": "Max Mustermann Updated",
"modifiedAt": "2026-02-07T11:00:00Z"
}
]
```
**Response**:
```json
{
"status": "received",
"action": "update",
"new_ids_count": 1,
"total_ids_in_batch": 1
}
```
### Beteiligte Delete Webhook
**Endpoint**: `POST /vmh/webhook/beteiligte/delete`
**Request Body**: Array von Entitäten
```json
[
{
"id": "entity-123",
"deletedAt": "2026-02-07T12:00:00Z"
}
]
```
**Response**:
```json
{
"status": "received",
"action": "delete",
"new_ids_count": 1,
"total_ids_in_batch": 1
}
```
### Webhook Features
**Batch Support**: Alle Webhooks unterstützen Arrays von Entitäten
**Deduplication**: Redis-basiert, verhindert Mehrfachverarbeitung
**Async Processing**: Events werden emittiert und asynchron verarbeitet
## Event Topics
Interne Event-Topics für Event-Driven Architecture (nicht direkt aufrufbar).
### calendar_sync_all
**Emitted by**: `calendar_sync_cron_step`, `calendar_sync_api_step`
**Subscribed by**: `calendar_sync_all_step`
**Payload**:
```json
{}
```
### calendar_sync_employee
**Emitted by**: `calendar_sync_all_step`, `calendar_sync_api_step`
**Subscribed by**: `calendar_sync_event_step`
**Payload**:
```json
{
"kuerzel": "SB",
"full_content": true
}
```
### vmh.beteiligte.create
**Emitted by**: `beteiligte_create_api_step`
**Subscribed by**: `beteiligte_sync_event_step`
**Payload**:
```json
{
"entity_id": "123",
"action": "create",
"source": "webhook",
"timestamp": "2026-02-07T10:00:00Z"
}
```
### vmh.beteiligte.update
**Emitted by**: `beteiligte_update_api_step`
**Subscribed by**: `beteiligte_sync_event_step`
**Payload**:
```json
{
"entity_id": "123",
"action": "update",
"source": "webhook",
"timestamp": "2026-02-07T11:00:00Z"
}
```
### vmh.beteiligte.delete
**Emitted by**: `beteiligte_delete_api_step`
**Subscribed by**: `beteiligte_sync_event_step`
**Payload**:
```json
{
"entity_id": "123",
"action": "delete",
"source": "webhook",
"timestamp": "2026-02-07T12:00:00Z"
}
```
## Rate Limits
### Google Calendar API
**Limit**: 600 requests/minute (enforced via Redis token bucket)
**Behavior**:
- Requests wait if rate limit reached
- Automatic backoff on 403 errors
- Max retry: 4 attempts
### Advoware API
**Limit**: Unknown (keine offizielle Dokumentation)
**Behavior**:
- 30s timeout per request
- Automatic token refresh on 401
- No retry logic (fail fast)
## Error Handling
### Standard Error Response
```json
{
"status": 400,
"body": {
"error": "Error description",
"details": "Detailed error message"
}
}
```
### HTTP Status Codes
- `200` - Success
- `400` - Bad Request (invalid input)
- `401` - Unauthorized (Advoware token invalid)
- `403` - Forbidden (rate limit)
- `404` - Not Found
- `500` - Internal Server Error
- `503` - Service Unavailable (Redis down)
### Common Errors
**Redis Connection Error**:
```json
{
"status": 503,
"body": {
"error": "Redis connection failed"
}
}
```
**Advoware API Error**:
```json
{
"status": 500,
"body": {
"error": "Advoware API call failed",
"details": "401 Unauthorized"
}
}
```
**Lock Active Error**:
```json
{
"status": 400,
"body": {
"error": "Sync already in progress for employee SB"
}
}
```
## API Versioning
**Current Version**: v1 (implicit, no version in URL)
**Future**: API versioning via URL prefix (`/v2/api/...`)
## Health Check
**Coming Soon**: `/health` endpoint für Load Balancer
Expected response:
```json
{
"status": "healthy",
"services": {
"redis": "up",
"advoware": "up",
"google": "up"
}
}
```
## Testing
### Postman Collection
Import diese Collection für schnelles Testing:
```json
{
"info": {
"name": "bitbylaw API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Advoware Proxy GET",
"request": {
"method": "GET",
"url": "http://localhost:3000/advoware/proxy?endpoint=employees"
}
},
{
"name": "Calendar Sync Trigger",
"request": {
"method": "POST",
"url": "http://localhost:3000/advoware/calendar/sync",
"header": [{"key": "Content-Type", "value": "application/json"}],
"body": {
"mode": "raw",
"raw": "{\"full_content\": true}"
}
}
}
]
}
```
## Related Documentation
- [Architecture](ARCHITECTURE.md)
- [Development Guide](DEVELOPMENT.md)
- [Configuration](CONFIGURATION.md)