feat: Seaca mobile API, enrollment, FCM push and admin UI (0.9.0)
Adds mobile device registration by admin codes, refresh tokens, push channel in notification policy, and Settings section for managing Seaca clients. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -17,7 +17,8 @@ from app.services.notification_settings import (
|
||||
VALID_SEVERITIES,
|
||||
)
|
||||
|
||||
DEFAULT_CHANNELS = frozenset({CHANNEL_TELEGRAM, CHANNEL_WEBHOOK, CHANNEL_EMAIL})
|
||||
CHANNEL_MOBILE = "mobile"
|
||||
DEFAULT_CHANNELS = frozenset({CHANNEL_TELEGRAM, CHANNEL_WEBHOOK, CHANNEL_EMAIL, CHANNEL_MOBILE})
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -26,6 +27,7 @@ class NotificationPolicyConfig:
|
||||
use_telegram: bool
|
||||
use_webhook: bool
|
||||
use_email: bool
|
||||
use_mobile: bool
|
||||
source: str # env | db
|
||||
|
||||
def allows_channel(self, channel: str) -> bool:
|
||||
@@ -35,21 +37,24 @@ class NotificationPolicyConfig:
|
||||
return self.use_webhook
|
||||
if channel == CHANNEL_EMAIL:
|
||||
return self.use_email
|
||||
if channel == CHANNEL_MOBILE:
|
||||
return self.use_mobile
|
||||
return False
|
||||
|
||||
|
||||
def _parse_channels_csv(value: str) -> tuple[bool, bool, bool]:
|
||||
def _parse_channels_csv(value: str) -> tuple[bool, bool, bool, bool]:
|
||||
parts = {p.strip().lower() for p in value.split(",") if p.strip()}
|
||||
return (
|
||||
CHANNEL_TELEGRAM in parts or "tg" in parts,
|
||||
CHANNEL_WEBHOOK in parts,
|
||||
CHANNEL_EMAIL in parts or "mail" in parts or "smtp" in parts,
|
||||
CHANNEL_MOBILE in parts or "push" in parts or "fcm" in parts,
|
||||
)
|
||||
|
||||
|
||||
def _policy_from_env() -> NotificationPolicyConfig:
|
||||
settings = get_settings()
|
||||
use_tg, use_wh, use_em = _parse_channels_csv(settings.notify_channels)
|
||||
use_tg, use_wh, use_em, use_mob = _parse_channels_csv(settings.notify_channels)
|
||||
min_sev = settings.notify_min_severity.strip() or "warning"
|
||||
if min_sev not in VALID_SEVERITIES:
|
||||
min_sev = "warning"
|
||||
@@ -58,6 +63,7 @@ def _policy_from_env() -> NotificationPolicyConfig:
|
||||
use_telegram=use_tg,
|
||||
use_webhook=use_wh,
|
||||
use_email=use_em,
|
||||
use_mobile=use_mob,
|
||||
source="env",
|
||||
)
|
||||
|
||||
@@ -86,6 +92,7 @@ def get_effective_notification_policy(db: Session | None = None) -> Notification
|
||||
use_telegram=bool(row.use_telegram),
|
||||
use_webhook=bool(row.use_webhook),
|
||||
use_email=bool(row.use_email),
|
||||
use_mobile=bool(getattr(row, "use_mobile", False)),
|
||||
source="db",
|
||||
)
|
||||
|
||||
@@ -104,6 +111,7 @@ def upsert_notification_policy(
|
||||
use_telegram: bool,
|
||||
use_webhook: bool,
|
||||
use_email: bool,
|
||||
use_mobile: bool = False,
|
||||
) -> NotificationPolicyConfig:
|
||||
if min_severity not in VALID_SEVERITIES:
|
||||
raise ValueError(f"invalid min_severity: {min_severity}")
|
||||
@@ -116,6 +124,7 @@ def upsert_notification_policy(
|
||||
use_telegram=use_telegram,
|
||||
use_webhook=use_webhook,
|
||||
use_email=use_email,
|
||||
use_mobile=use_mobile,
|
||||
)
|
||||
db.add(row)
|
||||
else:
|
||||
@@ -123,6 +132,7 @@ def upsert_notification_policy(
|
||||
row.use_telegram = use_telegram
|
||||
row.use_webhook = use_webhook
|
||||
row.use_email = use_email
|
||||
row.use_mobile = use_mobile
|
||||
|
||||
_sync_channel_min_severity(db, min_severity)
|
||||
db.commit()
|
||||
|
||||
Reference in New Issue
Block a user