feat: add scheduler and mail outbox

SMTP adapter with TLS and a fake, outbox with retries, backoff, rate limit and restart safety, scheduler tick with job-run records started by gunicorn, and a send_test_mail command.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N3t4WL7bd9bdHHNjEsxzqC
This commit is contained in:
2026-10-18 09:18:42 +02:00
co-authored by Claude Sonnet 5.5
parent 0dc079a8ac
commit 20510a73e5
40 changed files with 1315 additions and 6 deletions
+7
View File
@@ -25,6 +25,7 @@ DATA_DIR = _config.data_dir
DISPLAY_TIME_ZONE = _config.default_timezone
DIRECTORY = _config.directory
OIDC = _config.oidc
SMTP = _config.smtp
INSTALLED_APPS = [
"django.contrib.contenttypes",
@@ -34,6 +35,8 @@ INSTALLED_APPS = [
"portal.audit",
"portal.accounts",
"portal.shell",
"portal.mailer",
"portal.scheduler",
]
MIDDLEWARE = [
@@ -90,6 +93,10 @@ LANGUAGE_CODE = "en"
LANGUAGES = [("en", "English"), ("de", "Deutsch")]
LOCALE_PATHS = [BASE_DIR / "portal" / "locale"]
# E-mails use the portal-wide language and form of address (a per-device choice cannot reach
# server-sent mail). Becomes a runtime setting with the settings registry.
MAIL_LANGUAGE = "de"
# Static files served by whitenoise; assets are built into the image.
STATIC_URL = "static/"
STATIC_ROOT = BASE_DIR / "staticfiles"