feat(settings): add SMTP admin configuration

This commit is contained in:
Schubert Ferenc 2026-07-04 23:54:20 +02:00
parent c58e212e3a
commit 884a20e043
32 changed files with 1200 additions and 42 deletions

View file

@ -7,11 +7,13 @@ from sqlalchemy.orm import Session
from app.core.rbac import get_user_permission_names, require_permission
from app.db.database import get_db
from app.models.rbac import Role
from app.models.audit import AuditLog
from app.models.user import User
from app.repositories.customer_repository import CustomerRepository
from app.repositories.repair_repository import RepairRepository
from app.repositories.user_repository import UserRepository
from app.schemas.dashboard import DashboardSummary, EmptyWidget, MetricCard
from app.schemas.dashboard import DashboardSummary, EmptyWidget, MetricCard, SystemStatusItem
from app.services.system_settings_service import SystemSettingsService
logger = logging.getLogger(__name__)
@ -32,6 +34,7 @@ def get_dashboard_summary(
users: list[MetricCard] = []
roles: list[MetricCard] = []
repairs: list[MetricCard] = []
system_status: list[SystemStatusItem] = []
if "customers.read" in permissions:
customers = [
@ -69,6 +72,43 @@ def get_dashboard_summary(
MetricCard(label="Offen ohne Kundenmail", value=RepairRepository.count_open_repairs_without_customer_email(db)),
]
if "system_settings.manage" in permissions:
smtp_config = SystemSettingsService.get_smtp_runtime_config(db)
public_links = SystemSettingsService.get_public_links_settings(db)
latest_testmail = db.scalar(
select(AuditLog)
.where(AuditLog.action.in_(["system_settings.smtp.test_sent", "system_settings.smtp.test_failed"]))
.order_by(AuditLog.created_at.desc(), AuditLog.id.desc())
.limit(1)
)
latest_failed_status_mail = RepairRepository.latest_failed_status_mail(db)
system_status = [
SystemStatusItem(
label="SMTP-Konfiguration",
value={
"database": "Admin-Konfiguration",
"environment": "Umgebung",
"missing": "Nicht konfiguriert",
}[smtp_config.source],
status="ok" if smtp_config.is_configured else "warning",
),
SystemStatusItem(
label="Public Status Base URL",
value=public_links.repair_status_base_url or "Nicht konfiguriert",
status="ok" if public_links.repair_status_base_url else "warning",
),
SystemStatusItem(
label="Letzte SMTP-Testmail",
value=latest_testmail.created_at.isoformat() if latest_testmail else "Noch keine Testmail",
status="info" if latest_testmail else "warning",
),
SystemStatusItem(
label="Letzte fehlgeschlagene Statusmail",
value=latest_failed_status_mail.created_at.isoformat() if latest_failed_status_mail else "Keine Fehler",
status="warning" if latest_failed_status_mail else "ok",
),
]
logger.info("dashboard.summary", extra={"actor_user_id": current_user.id})
return DashboardSummary(
@ -77,6 +117,7 @@ def get_dashboard_summary(
users=users,
roles=roles,
repairs=repairs,
system_status=system_status,
activities=EmptyWidget(
title="Letzte Aktivitäten",
message="Noch keine Aktivitäten vorhanden.",