Spaces:
Running
Running
File size: 5,103 Bytes
bb6d7b4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
"""
Subscription models for the application.
This module defines database models for subscription management.
"""
from enum import Enum
from sqlalchemy import Column, Integer, String, Float, Boolean, DateTime, ForeignKey, Enum as SQLAlchemyEnum
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from src.models.base import Base
class SubscriptionTier(str, Enum):
"""Subscription tier enum."""
FREE = "FREE"
BASIC = "BASIC"
PROFESSIONAL = "PROFESSIONAL"
ENTERPRISE = "ENTERPRISE"
class BillingPeriod(str, Enum):
"""Billing period enum."""
MONTHLY = "MONTHLY"
ANNUALLY = "ANNUALLY"
CUSTOM = "CUSTOM"
class SubscriptionPlan(Base):
"""Subscription plan model."""
__tablename__ = "subscription_plans"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(100), nullable=False)
tier = Column(SQLAlchemyEnum(SubscriptionTier), nullable=False)
description = Column(String(500))
price_monthly = Column(Float, nullable=False)
price_annually = Column(Float, nullable=False)
is_active = Column(Boolean, default=True)
# Features
max_alerts = Column(Integer, default=10)
max_reports = Column(Integer, default=5)
max_searches_per_day = Column(Integer, default=20)
max_monitoring_keywords = Column(Integer, default=10)
max_data_retention_days = Column(Integer, default=30)
supports_api_access = Column(Boolean, default=False)
supports_live_feed = Column(Boolean, default=False)
supports_dark_web_monitoring = Column(Boolean, default=False)
supports_export = Column(Boolean, default=False)
supports_advanced_analytics = Column(Boolean, default=False)
# Stripe product ID (for integration with Stripe)
stripe_product_id = Column(String(100))
stripe_monthly_price_id = Column(String(100))
stripe_annual_price_id = Column(String(100))
# Timestamps
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Relationships
subscriptions = relationship("UserSubscription", back_populates="plan")
def __repr__(self):
return f"<SubscriptionPlan(id={self.id}, name={self.name}, tier={self.tier})>"
class SubscriptionStatus(str, Enum):
"""Subscription status enum."""
ACTIVE = "ACTIVE"
PAST_DUE = "PAST_DUE"
CANCELED = "CANCELED"
TRIALING = "TRIALING"
INCOMPLETE = "INCOMPLETE"
INCOMPLETE_EXPIRED = "INCOMPLETE_EXPIRED"
class UserSubscription(Base):
"""User subscription model."""
__tablename__ = "user_subscriptions"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
plan_id = Column(Integer, ForeignKey("subscription_plans.id"), nullable=False)
status = Column(SQLAlchemyEnum(SubscriptionStatus), nullable=False, default=SubscriptionStatus.ACTIVE)
# Billing details
billing_period = Column(SQLAlchemyEnum(BillingPeriod), nullable=False, default=BillingPeriod.MONTHLY)
current_period_start = Column(DateTime(timezone=True))
current_period_end = Column(DateTime(timezone=True))
# Stripe subscription ID
stripe_subscription_id = Column(String(100))
stripe_customer_id = Column(String(100))
# Timestamps
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
canceled_at = Column(DateTime(timezone=True))
# Relationships
user = relationship("User", back_populates="subscriptions")
plan = relationship("SubscriptionPlan", back_populates="subscriptions")
payment_history = relationship("PaymentHistory", back_populates="subscription")
def __repr__(self):
return f"<UserSubscription(id={self.id}, user_id={self.user_id}, plan_id={self.plan_id})>"
class PaymentStatus(str, Enum):
"""Payment status enum."""
SUCCEEDED = "SUCCEEDED"
PENDING = "PENDING"
FAILED = "FAILED"
REFUNDED = "REFUNDED"
class PaymentHistory(Base):
"""Payment history model."""
__tablename__ = "payment_history"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
subscription_id = Column(Integer, ForeignKey("user_subscriptions.id"), nullable=False)
amount = Column(Float, nullable=False)
currency = Column(String(3), default="USD")
status = Column(SQLAlchemyEnum(PaymentStatus), nullable=False)
# Stripe payment intent ID
stripe_payment_intent_id = Column(String(100))
stripe_invoice_id = Column(String(100))
# Timestamps
payment_date = Column(DateTime(timezone=True), server_default=func.now())
# Relationships
user = relationship("User")
subscription = relationship("UserSubscription", back_populates="payment_history")
def __repr__(self):
return f"<PaymentHistory(id={self.id}, user_id={self.user_id}, amount={self.amount}, status={self.status})>" |