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
Benjamin Admin bfdaf63ba9 fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:51:32 +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)