mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-10-29 08:07:37 +09:00
Reusable, non-blocking notification layer on top of the Queue Bus: notify.send(event, to, data) records a Notification + per-channel NotificationDelivery, queues them, and a daemon consumer delivers via pluggable channel adapters (in-app, email, chat) inheriting retry, backoff and dead-letter. - Jinja2 email system: branded, dark-mode, Outlook-safe base layout + per-event templates (security/backup/monitoring/welcome/invitation). The legacy inline f-string email was removed and now renders here. - In-app center API (inbox/unread-count/mark-read) + per-user Socket.IO push. - Admin delivery log (stats/filter/retry). - Email providers (SMTP/SendGrid/Postmark/SES/Mailgun) with encrypted credentials + test; the email adapter prefers the default provider and falls back to the legacy SMTP config; surfaced in ConnectionRegistry. - NotificationService.send_all() is now a non-blocking shim that routes system alerts through the bus. Migrations 023 + 024. Tests: backend/tests/test_notification_bus.py (20). Full suite: 391 passed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
19 lines
819 B
Python
19 lines
819 B
Python
"""ServerKit Notification Bus.
|
|
|
|
A reusable, queue-backed notification layer built on top of the Queue Bus.
|
|
|
|
Any part of the app (or a plugin) emits an event:
|
|
|
|
from app.plugins_sdk import notify
|
|
notify.send('backup.completed', to='admins', data={'app': 'blog', 'size': '2.3 GB'})
|
|
|
|
The call is non-blocking: it writes a durable ``Notification`` record plus one
|
|
``NotificationDelivery`` per (recipient x channel), enqueues them on the Queue
|
|
Bus, and returns. A background ``NotificationConsumer`` renders each delivery
|
|
and hands it to the matching channel adapter (in-app, email, chat, ...).
|
|
|
|
Submodules (``models``, ``service``, ``sdk``, ``consumer``, ``channels``,
|
|
``rendering``, ``catalog``) are imported lazily by their consumers to keep
|
|
model registration (``app.models.__init__``) free of heavy imports.
|
|
"""
|