"""Plan model. Tier limits live in `config` JSON, editable in admin without redeploy.""" from datetime import datetime from app.utils.time import utcnow from sqlalchemy import JSON from app.extensions import db class Plan(db.Model): __tablename__ = "plans" id = db.Column(db.BigInteger().with_variant(db.Integer, "sqlite"), primary_key=True, autoincrement=True) slug = db.Column(db.String(40), unique=True, nullable=False) # free|basic|pro|business name = db.Column(db.String(80), nullable=False) price_monthly_cents = db.Column(db.Integer, nullable=False, default=0) stripe_price_id = db.Column(db.String(80), nullable=True) config = db.Column(JSON, nullable=False, default=dict) # limits (Section 6) is_active = db.Column(db.Boolean, nullable=False, default=True) sort_order = db.Column(db.Integer, nullable=False, default=0) created_at = db.Column(db.DateTime, default=utcnow, nullable=False) updated_at = db.Column(db.DateTime, default=utcnow, onupdate=utcnow, nullable=False) users = db.relationship("User", back_populates="tier", lazy="dynamic") def limit(self, key, default=None): """Read a single limit from config JSON.""" return (self.config or {}).get(key, default) def __repr__(self): return f""