pounce/backend/app/models/price_alert.py
Yves Gugger 0582b26be7
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
feat: Add user deletion in admin panel and fix OAuth authentication
- Add delete user functionality with cascade deletion of all user data
- Fix OAuth URLs to include /api/v1 path
- Fix token storage key consistency in OAuth callback
- Update user model to cascade delete price alerts
- Improve email templates with minimalist design
- Add confirmation dialog for user deletion
- Prevent deletion of admin users
2025-12-09 21:45:40 +01:00

57 lines
2.1 KiB
Python

"""Price Alert model for TLD price notifications."""
from datetime import datetime
from typing import Optional
from sqlalchemy import String, Float, Boolean, DateTime, Integer, ForeignKey, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
class PriceAlert(Base):
"""
Price Alert model for tracking user's TLD price subscriptions.
Users can subscribe to price alerts for specific TLDs and get notified
when prices change by a certain threshold.
"""
__tablename__ = "price_alerts"
__table_args__ = (
UniqueConstraint('user_id', 'tld', name='unique_user_tld_alert'),
)
id: Mapped[int] = mapped_column(primary_key=True, index=True)
# User who created the alert
user_id: Mapped[int] = mapped_column(Integer, ForeignKey("users.id"), nullable=False)
# TLD to monitor (without dot, e.g., "com", "io")
tld: Mapped[str] = mapped_column(String(50), index=True, nullable=False)
# Alert settings
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
# Optional: only alert if price drops below this threshold
target_price: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
# Optional: only alert if price changes by this percentage
threshold_percent: Mapped[float] = mapped_column(Float, default=5.0) # 5% default
# Track last notification to avoid spam
last_notified_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
last_notified_price: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
# Timestamps
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
updated_at: Mapped[datetime] = mapped_column(
DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
)
# Relationship to user
user: Mapped["User"] = relationship("User", back_populates="price_alerts")
def __repr__(self) -> str:
status = "active" if self.is_active else "paused"
return f"<PriceAlert user={self.user_id} tld=.{self.tld} ({status})>"