@startuml title Polling Architecture with Security !define SECURITY_COLOR #FFE6E6 !define APP_COLOR #E6F3FF !define DATA_COLOR #E6FFE6 rectangle "Event Happens" as Event APP_COLOR rectangle "Sanitize & Rate Check" as Sanitize SECURITY_COLOR database "notifications table" as DB DATA_COLOR rectangle "REST API\n(session auth + rate limit)" as API SECURITY_COLOR rectangle "Frontend Poller\n(30s interval)" as Frontend APP_COLOR rectangle "Browser Notification\n(text-only)" as Browser SECURITY_COLOR Event --> Sanitize : bleach.clean() Sanitize --> DB : INSERT if under 100/min Frontend --> API : GET /api/notifications/unread API --> DB : SELECT WHERE user_id = ? DB --> API : JSON array API --> Frontend : sanitized text Frontend --> Browser : plain text display note right of Sanitize Security Layer 1: - Strip all HTML/JS - Check user preferences - Rate limit: 100/user/min end note note right of API Security Layer 2: - Session authentication - Flask-Limiter: 120/min - user_id filter in SQL end note note right of Browser Security Layer 3: - No HTML rendering - User permission required - Text-only display end note note bottom of DB Simple Schema: - id, user_id, event_type - message_text (sanitized) - created_at, read_at - Auto-delete after 30 days end note @enduml