""" Database Models for Web Push Notification Service This module defines the SQLAlchemy models for managing web push notifications, including VAPID keys, user subscriptions, and application settings. Author: Matthew Raymer Created: 2025 """ from flask_sqlalchemy import SQLAlchemy from typing import List, Optional db = SQLAlchemy() class VAPIDKey(db.Model): """ Stores VAPID (Voluntary Application Server Identification) keys for web push authentication. VAPID keys are used to identify the application server to push services and establish a trust relationship for sending notifications. Attributes: id (int): Primary key identifier public_key (str): Base64-encoded public VAPID key (max 255 chars) private_key (str): Base64-encoded private VAPID key (max 255 chars) subscriptions (List[Subscription]): Related push notification subscriptions """ id = db.Column(db.Integer, primary_key=True) public_key = db.Column(db.String(255), nullable=False) private_key = db.Column(db.String(255), nullable=False) subscriptions = db.relationship('Subscription', backref='vapid_key', lazy=True) class Settings(db.Model): """ Application settings and state management for notification processing. Tracks the execution state of notification jobs to prevent duplicate processing and maintain notification history. Attributes: id (int): Primary key identifier prev_notify_end_time (str): ISO 8601 timestamp of last completed notification run running_notify_end_time (Optional[str]): ISO 8601 timestamp of currently running notification job, or None if no job is running """ id = db.Column(db.Integer, primary_key=True) prev_notify_end_time = db.Column(db.String(29), nullable=False) running_notify_end_time = db.Column(db.String(29), nullable=True) class Subscription(db.Model): """ User subscription details for web push notifications. Stores the necessary information to send push notifications to a specific browser/device, including encryption keys and notification preferences. Attributes: id (int): Primary key identifier auth (str): Authentication secret for push encryption (max 255 chars) created_date (Optional[str]): ISO 8601 timestamp of subscription creation endpoint (str): Push service URL for this subscription (max 500 chars) message (Optional[str]): Custom message for direct notifications (max 100 chars) notify_time (str): Daily notification time in "HH:MM" format (UTC) notify_type (Optional[str]): Type of notification subscription Valid values: - 'DAILY_CHECK': Regular daily notifications - 'DIRECT_NOTIFICATION': One-time direct notifications p256dh (str): Client's public key for push encryption (max 255 chars) vapid_key_id (int): Foreign key reference to associated VAPID key Relationships: vapid_key: References the VAPID key used for this subscription Note: The endpoint URL is unique per browser/device/user combination and serves as the primary identifier for the subscription from the push service's perspective. """ id = db.Column(db.Integer, primary_key=True) auth = db.Column(db.String(255), nullable=False) created_date = db.Column(db.String(29), nullable=True) endpoint = db.Column(db.String(500), nullable=False) message = db.Column(db.String(100), nullable=True) notify_time = db.Column(db.String(5), nullable=False) # HH:MM notify_type = db.Column(db.String(32), nullable=True) # 'DAILY_CHECK', 'DIRECT_NOTIFICATION' p256dh = db.Column(db.String(255), nullable=False) vapid_key_id = db.Column(db.Integer, db.ForeignKey('vapid_key.id'), nullable=False)