admin-panel/backend/app/models.py

152 lines
5.8 KiB
Python

"""
Admin Panel Database Models
"""
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
import bcrypt
db = SQLAlchemy()
class AdminUser(db.Model):
"""Admin users table"""
__tablename__ = 'admin_users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password_hash = db.Column(db.String(255), nullable=False)
full_name = db.Column(db.String(100))
role = db.Column(db.String(20), default='admin') # admin, super_admin
is_active = db.Column(db.Boolean, default=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
last_login = db.Column(db.DateTime)
def set_password(self, password):
"""Hash and set password"""
self.password_hash = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
def check_password(self, password):
"""Verify password"""
return bcrypt.checkpw(password.encode('utf-8'), self.password_hash.encode('utf-8'))
def to_dict(self):
return {
'id': self.id,
'username': self.username,
'email': self.email,
'full_name': self.full_name,
'role': self.role,
'is_active': self.is_active,
'created_at': self.created_at.isoformat() if self.created_at else None,
'last_login': self.last_login.isoformat() if self.last_login else None,
}
class SubscriptionPlan(db.Model):
"""Subscription plans table"""
__tablename__ = 'subscription_plans'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), unique=True, nullable=False)
slug = db.Column(db.String(50), unique=True, nullable=False)
description = db.Column(db.Text)
price_monthly = db.Column(db.Numeric(10, 2), default=0)
price_yearly = db.Column(db.Numeric(10, 2), default=0)
# Limits
max_domains = db.Column(db.Integer, default=1)
max_containers = db.Column(db.Integer, default=1)
max_storage_gb = db.Column(db.Integer, default=10)
max_bandwidth_gb = db.Column(db.Integer, default=100)
# Features (JSON)
features = db.Column(db.JSON, default=list)
is_active = db.Column(db.Boolean, default=True)
is_visible = db.Column(db.Boolean, default=True)
sort_order = db.Column(db.Integer, default=0)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
def to_dict(self):
return {
'id': self.id,
'name': self.name,
'slug': self.slug,
'description': self.description,
'price_monthly': float(self.price_monthly) if self.price_monthly else 0,
'price_yearly': float(self.price_yearly) if self.price_yearly else 0,
'max_domains': self.max_domains,
'max_containers': self.max_containers,
'max_storage_gb': self.max_storage_gb,
'max_bandwidth_gb': self.max_bandwidth_gb,
'features': self.features or [],
'is_active': self.is_active,
'is_visible': self.is_visible,
'sort_order': self.sort_order,
'created_at': self.created_at.isoformat() if self.created_at else None,
'updated_at': self.updated_at.isoformat() if self.updated_at else None,
}
class CloudflareAccount(db.Model):
"""Company Cloudflare accounts"""
__tablename__ = 'cloudflare_accounts'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
email = db.Column(db.String(120), nullable=False)
api_token = db.Column(db.Text, nullable=False) # Encrypted
max_domains = db.Column(db.Integer, default=100)
current_domains = db.Column(db.Integer, default=0)
notes = db.Column(db.Text)
is_active = db.Column(db.Boolean, default=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
def to_dict(self, include_token=False):
data = {
'id': self.id,
'name': self.name,
'email': self.email,
'max_domains': self.max_domains,
'current_domains': self.current_domains,
'notes': self.notes,
'is_active': self.is_active,
'created_at': self.created_at.isoformat() if self.created_at else None,
'updated_at': self.updated_at.isoformat() if self.updated_at else None,
}
if include_token:
data['api_token'] = self.api_token
return data
class AuditLog(db.Model):
"""Audit logs for admin actions"""
__tablename__ = 'audit_logs'
id = db.Column(db.Integer, primary_key=True)
admin_id = db.Column(db.Integer, db.ForeignKey('admin_users.id'))
action = db.Column(db.String(100), nullable=False)
resource_type = db.Column(db.String(50)) # customer, plan, cf_account
resource_id = db.Column(db.Integer)
details = db.Column(db.JSON)
ip_address = db.Column(db.String(45))
created_at = db.Column(db.DateTime, default=datetime.utcnow)
admin = db.relationship('AdminUser', backref='audit_logs')
def to_dict(self):
return {
'id': self.id,
'admin_id': self.admin_id,
'admin_username': self.admin.username if self.admin else None,
'action': self.action,
'resource_type': self.resource_type,
'resource_id': self.resource_id,
'details': self.details,
'ip_address': self.ip_address,
'created_at': self.created_at.isoformat() if self.created_at else None,
}