feat(notifications): täglicher Lauf über SMTP und Apprise
- Kanäle SMTP (HTML-Mail mit Logos als CID-Anhang) und Apprise, beide blockierenden Bibliotheken laufen in einem Thread - Vier Anlässe: Fälligkeiten im Vorlauf, Kündigungsfristen in drei Stufen, überschrittene Budgets je Monat, Vertragsverlängerungen im Folgemonat - APScheduler im Anwendungsprozess, täglich 07:00 Europe/Berlin, räumt zugleich abgelaufene Sitzungen auf - Duplikatsschutz über den Zieltag statt den Versandtag; fehlgeschlagener Versand wird beim nächsten Lauf erneut versucht - Endpunkte für Regeln, Protokoll, Testversand und sofortigen Lauf - Einstellungsseite mit Einrichtungsstand, Regelpflege und Protokoll - 25 neue Backend-Tests (260 gesamt), 9 neue Frontend-Tests (74 gesamt) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014e7t8UpmoVNMtWivY5LiSH
This commit is contained in:
@@ -11,6 +11,7 @@ from app.api.router import api_router
|
||||
from app.core.config import settings
|
||||
from app.core.errors import register_exception_handlers
|
||||
from app.db.session import SessionLocal, engine
|
||||
from app.scheduler import shutdown_scheduler, start_scheduler
|
||||
from app.services.auth import ensure_admin_user, purge_expired_refresh_tokens
|
||||
|
||||
logging.basicConfig(
|
||||
@@ -25,8 +26,10 @@ async def lifespan(_: FastAPI) -> AsyncGenerator[None, None]:
|
||||
"""Start- und Stopplogik der Anwendung."""
|
||||
settings.logo_storage_dir.mkdir(parents=True, exist_ok=True)
|
||||
await _bootstrap()
|
||||
start_scheduler()
|
||||
logger.info("moneyfy %s gestartet (%s)", settings.app_version, settings.environment)
|
||||
yield
|
||||
shutdown_scheduler()
|
||||
await engine.dispose()
|
||||
logger.info("moneyfy wird beendet")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user