This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/backend/email_template_api.py
BreakPilot Dev 19855efacc
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed
feat: BreakPilot PWA - Full codebase (clean push without large binaries)
All services: admin-v2, studio-v2, website, ai-compliance-sdk,
consent-service, klausur-service, voice-service, and infrastructure.
Large PDFs and compiled binaries excluded via .gitignore.
2026-02-11 13:25:58 +01:00

253 lines
8.5 KiB
Python

"""
E-Mail Template API für BreakPilot
Proxy für den Go Consent Service E-Mail Template Management
"""
from fastapi import APIRouter, Request, HTTPException, Depends
from fastapi.responses import JSONResponse
import httpx
from typing import Optional
import os
from consent_client import CONSENT_SERVICE_URL, generate_jwt_token
router = APIRouter(prefix="/api/consent/admin/email-templates", tags=["Email Templates"])
# Base URL für E-Mail-Template-Endpunkte im Go Consent Service
EMAIL_TEMPLATE_BASE = f"{CONSENT_SERVICE_URL}/api/v1/admin"
async def get_admin_token() -> str:
"""Generiert einen Admin-Token für API-Calls zum Consent Service"""
return generate_jwt_token(
user_id="a0000000-0000-0000-0000-000000000001",
email="admin@breakpilot.app",
role="admin",
expires_hours=1
)
async def proxy_request(
method: str,
path: str,
token: str,
json_data: dict = None,
params: dict = None
) -> dict:
"""Proxy-Funktion für API-Calls zum Go Consent Service"""
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
url = f"{EMAIL_TEMPLATE_BASE}{path}"
async with httpx.AsyncClient(timeout=30.0) as client:
try:
if method == "GET":
response = await client.get(url, headers=headers, params=params)
elif method == "POST":
response = await client.post(url, headers=headers, json=json_data)
elif method == "PUT":
response = await client.put(url, headers=headers, json=json_data)
elif method == "DELETE":
response = await client.delete(url, headers=headers)
else:
raise ValueError(f"Unsupported method: {method}")
if response.status_code >= 400:
error_detail = response.text
try:
error_detail = response.json().get("error", response.text)
except:
pass
raise HTTPException(status_code=response.status_code, detail=error_detail)
if response.status_code == 204:
return {"success": True}
return response.json()
except httpx.RequestError as e:
raise HTTPException(status_code=503, detail=f"Consent Service nicht erreichbar: {str(e)}")
# ==========================================
# E-Mail Template Typen
# ==========================================
@router.get("/types")
async def get_all_template_types():
"""Gibt alle verfügbaren E-Mail-Template-Typen zurück"""
token = await get_admin_token()
return await proxy_request("GET", "/email-templates/types", token)
# ==========================================
# E-Mail Templates
# ==========================================
@router.get("")
async def get_all_templates():
"""Gibt alle E-Mail-Templates zurück"""
token = await get_admin_token()
return await proxy_request("GET", "/email-templates", token)
@router.post("")
async def create_template(request: Request):
"""Erstellt ein neues E-Mail-Template"""
token = await get_admin_token()
data = await request.json()
return await proxy_request("POST", "/email-templates", token, json_data=data)
@router.get("/settings")
async def get_settings():
"""Gibt die E-Mail-Einstellungen zurück"""
token = await get_admin_token()
return await proxy_request("GET", "/email-templates/settings", token)
@router.put("/settings")
async def update_settings(request: Request):
"""Aktualisiert die E-Mail-Einstellungen"""
token = await get_admin_token()
data = await request.json()
return await proxy_request("PUT", "/email-templates/settings", token, json_data=data)
@router.get("/stats")
async def get_email_stats():
"""Gibt E-Mail-Statistiken zurück"""
token = await get_admin_token()
return await proxy_request("GET", "/email-templates/stats", token)
@router.get("/logs")
async def get_send_logs(
template_id: Optional[str] = None,
status: Optional[str] = None,
limit: int = 100,
offset: int = 0
):
"""Gibt E-Mail-Send-Logs zurück"""
token = await get_admin_token()
params = {"limit": limit, "offset": offset}
if template_id:
params["template_id"] = template_id
if status:
params["status"] = status
return await proxy_request("GET", "/email-templates/logs", token, params=params)
@router.get("/default/{template_type}")
async def get_default_content(template_type: str):
"""Gibt den Default-Inhalt für einen Template-Typ zurück"""
token = await get_admin_token()
return await proxy_request("GET", f"/email-templates/default/{template_type}", token)
@router.post("/initialize")
async def initialize_templates():
"""Initialisiert alle Standard-Templates"""
token = await get_admin_token()
return await proxy_request("POST", "/email-templates/initialize", token)
@router.get("/{template_id}")
async def get_template(template_id: str):
"""Gibt ein einzelnes E-Mail-Template zurück"""
token = await get_admin_token()
return await proxy_request("GET", f"/email-templates/{template_id}", token)
@router.get("/{template_id}/versions")
async def get_template_versions(template_id: str):
"""Gibt alle Versionen eines Templates zurück"""
token = await get_admin_token()
return await proxy_request("GET", f"/email-templates/{template_id}/versions", token)
# ==========================================
# E-Mail Template Versionen
# ==========================================
versions_router = APIRouter(prefix="/api/consent/admin/email-template-versions", tags=["Email Template Versions"])
@versions_router.get("/{version_id}")
async def get_version(version_id: str):
"""Gibt eine einzelne Version zurück"""
token = await get_admin_token()
return await proxy_request("GET", f"/email-template-versions/{version_id}", token)
@versions_router.post("")
async def create_version(request: Request):
"""Erstellt eine neue Version"""
token = await get_admin_token()
data = await request.json()
return await proxy_request("POST", "/email-template-versions", token, json_data=data)
@versions_router.put("/{version_id}")
async def update_version(version_id: str, request: Request):
"""Aktualisiert eine Version"""
token = await get_admin_token()
data = await request.json()
return await proxy_request("PUT", f"/email-template-versions/{version_id}", token, json_data=data)
@versions_router.post("/{version_id}/submit")
async def submit_for_review(version_id: str):
"""Sendet eine Version zur Überprüfung"""
token = await get_admin_token()
return await proxy_request("POST", f"/email-template-versions/{version_id}/submit", token)
@versions_router.post("/{version_id}/approve")
async def approve_version(version_id: str, request: Request):
"""Genehmigt eine Version"""
token = await get_admin_token()
data = await request.json()
return await proxy_request("POST", f"/email-template-versions/{version_id}/approve", token, json_data=data)
@versions_router.post("/{version_id}/reject")
async def reject_version(version_id: str, request: Request):
"""Lehnt eine Version ab"""
token = await get_admin_token()
data = await request.json()
return await proxy_request("POST", f"/email-template-versions/{version_id}/reject", token, json_data=data)
@versions_router.post("/{version_id}/publish")
async def publish_version(version_id: str):
"""Veröffentlicht eine Version"""
token = await get_admin_token()
return await proxy_request("POST", f"/email-template-versions/{version_id}/publish", token)
@versions_router.get("/{version_id}/approvals")
async def get_approvals(version_id: str):
"""Gibt die Genehmigungshistorie einer Version zurück"""
token = await get_admin_token()
return await proxy_request("GET", f"/email-template-versions/{version_id}/approvals", token)
@versions_router.post("/{version_id}/preview")
async def preview_version(version_id: str, request: Request):
"""Generiert eine Vorschau einer Version"""
token = await get_admin_token()
data = await request.json()
return await proxy_request("POST", f"/email-template-versions/{version_id}/preview", token, json_data=data)
@versions_router.post("/{version_id}/send-test")
async def send_test_email(version_id: str, request: Request):
"""Sendet eine Test-E-Mail"""
token = await get_admin_token()
data = await request.json()
return await proxy_request("POST", f"/email-template-versions/{version_id}/send-test", token, json_data=data)