62 lines
2.2 KiB
Python
62 lines
2.2 KiB
Python
"""Plan model for subscription tiers."""
|
|
import logging
|
|
from datetime import datetime, timezone
|
|
from sqlalchemy import Column, String, Integer, Boolean, DateTime, Text
|
|
from gatehouse_app.models.base import BaseModel
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class Plan(BaseModel):
|
|
"""Subscription plan definition.
|
|
|
|
Represents different pricing tiers that organizations can subscribe to.
|
|
"""
|
|
__tablename__ = "plans"
|
|
|
|
name = Column(String(100), nullable=False)
|
|
slug = Column(String(50), unique=True, nullable=False)
|
|
description = Column(Text, nullable=True)
|
|
|
|
# Pricing in cents
|
|
price_monthly = Column(Integer, nullable=False, default=0) # Price in cents
|
|
price_yearly = Column(Integer, nullable=False, default=0) # Price in cents
|
|
|
|
# User limits
|
|
included_users = Column(Integer, nullable=False, default=0) # 0 = unlimited
|
|
|
|
# Overage pricing (cents per user over limit)
|
|
overage_rate_per_user = Column(Integer, nullable=False, default=0)
|
|
|
|
# Feature flags (JSON)
|
|
features = Column(Text, nullable=True) # JSON string
|
|
|
|
# Stripe integration
|
|
stripe_price_id_monthly = Column(String(100), nullable=True)
|
|
stripe_price_id_yearly = Column(String(100), nullable=True)
|
|
|
|
# Active/inactive
|
|
is_active = Column(Boolean, nullable=False, default=True)
|
|
|
|
def __repr__(self):
|
|
return f"<Plan {self.slug}: ${self.price_monthly / 100}/mo>"
|
|
|
|
def to_dict(self):
|
|
"""Convert plan to dictionary."""
|
|
return {
|
|
"id": self.id,
|
|
"name": self.name,
|
|
"slug": self.slug,
|
|
"description": self.description,
|
|
"price_monthly": self.price_monthly,
|
|
"price_yearly": self.price_yearly,
|
|
"included_users": self.included_users,
|
|
"overage_rate_per_user": self.overage_rate_per_user,
|
|
"features": self.features,
|
|
"stripe_price_id_monthly": self.stripe_price_id_monthly,
|
|
"stripe_price_id_yearly": self.stripe_price_id_yearly,
|
|
"is_active": self.is_active,
|
|
"created_at": self.created_at.isoformat() + "Z" if self.created_at else None,
|
|
"updated_at": self.updated_at.isoformat() + "Z" if self.updated_at else None,
|
|
}
|