Files
orion/app/modules/tenancy/models/admin.py
Samir Boulahtit aad18c27ab
Some checks failed
CI / ruff (push) Successful in 11s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has started running
refactor: remove all backward compatibility code across 70 files
Clean up 28 backward compatibility instances identified in the codebase.
The app is not live, so all shims are replaced with the target architecture:

- Remove legacy Inventory.location column (use bin_location exclusively)
- Remove dashboard _extract_metric_value helper (use flat metrics dict)
- Remove legacy stat field duplicates (total_stores, total_imports, etc.)
- Remove 13 re-export shims and class aliases across modules
- Remove module-enabling JSON fallback (use PlatformModule junction table)
- Remove menu_to_legacy_format() conversion (return dataclasses directly)
- Remove title/description from MarketplaceProductBase schema
- Clean billing convenience method docstrings
- Clean test fixtures and backward-compat comments
- Add PlatformModule seeding to init_production.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 13:20:29 +01:00

203 lines
7.1 KiB
Python

# app/modules/tenancy/models/admin.py
"""
Admin-specific database models.
This module provides models for:
- Admin audit logging (compliance and security tracking)
- Admin notifications (system alerts and warnings)
- Platform settings (global configuration)
- Platform alerts (system-wide issues)
- Application logs (critical events logging)
"""
from sqlalchemy import (
JSON,
Boolean,
Column,
DateTime,
ForeignKey,
Integer,
String,
Text,
)
from sqlalchemy.orm import relationship
from app.core.database import Base
from models.database.base import TimestampMixin
class AdminAuditLog(Base, TimestampMixin):
"""
Track all admin actions for compliance and security.
Separate from regular audit logs - focuses on admin-specific operations
like store creation, user management, and system configuration changes.
"""
__tablename__ = "admin_audit_logs"
id = Column(Integer, primary_key=True, index=True)
admin_user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
action = Column(
String(100), nullable=False, index=True
) # create_store, delete_store, etc.
target_type = Column(
String(50), nullable=False, index=True
) # store, user, import_job, setting
target_id = Column(String(100), nullable=False, index=True)
details = Column(JSON) # Additional context about the action
ip_address = Column(String(45)) # IPv4 or IPv6
user_agent = Column(Text)
request_id = Column(String(100)) # For correlating with application logs
# Relationships
admin_user = relationship("User", foreign_keys=[admin_user_id])
def __repr__(self):
return f"<AdminAuditLog(id={self.id}, action='{self.action}', target={self.target_type}:{self.target_id})>"
class AdminSetting(Base, TimestampMixin):
"""
Platform-wide admin settings and configuration.
Stores global settings that affect the entire platform, different from
store-specific settings. Supports encryption for sensitive values.
Examples:
- max_stores_allowed
- maintenance_mode
- default_store_trial_days
- smtp_settings
- stripe_api_keys (encrypted)
"""
__tablename__ = "admin_settings"
id = Column(Integer, primary_key=True, index=True)
key = Column(String(100), unique=True, nullable=False, index=True)
value = Column(Text, nullable=False)
value_type = Column(String(20), default="string") # string, integer, boolean, json
category = Column(
String(50), index=True
) # system, security, marketplace, notifications
description = Column(Text)
is_encrypted = Column(Boolean, default=False)
is_public = Column(Boolean, default=False) # Can be exposed to frontend?
last_modified_by_user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
# Relationships
last_modified_by = relationship("User", foreign_keys=[last_modified_by_user_id])
def __repr__(self):
return f"<AdminSetting(key='{self.key}', category='{self.category}')>"
class PlatformAlert(Base, TimestampMixin):
"""
System-wide alerts that admins need to be aware of.
Tracks platform issues, performance problems, security incidents,
and other system-level concerns that require admin attention.
"""
__tablename__ = "platform_alerts"
id = Column(Integer, primary_key=True, index=True)
alert_type = Column(
String(50), nullable=False, index=True
) # security, performance, capacity, integration
severity = Column(
String(20), nullable=False, index=True
) # info, warning, error, critical
title = Column(String(200), nullable=False)
description = Column(Text)
affected_stores = Column(JSON) # List of affected store IDs
affected_systems = Column(JSON) # List of affected system components
is_resolved = Column(Boolean, default=False, index=True)
resolved_at = Column(DateTime, nullable=True)
resolved_by_user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
resolution_notes = Column(Text)
auto_generated = Column(Boolean, default=True) # System-generated vs manual
occurrence_count = Column(Integer, default=1) # Track repeated occurrences
first_occurred_at = Column(DateTime, nullable=False)
last_occurred_at = Column(DateTime, nullable=False)
# Relationships
resolved_by = relationship("User", foreign_keys=[resolved_by_user_id])
def __repr__(self):
return f"<PlatformAlert(id={self.id}, type='{self.alert_type}', severity='{self.severity}')>"
class AdminSession(Base, TimestampMixin):
"""
Track admin login sessions for security monitoring.
Helps identify suspicious login patterns, track concurrent sessions,
and enforce session policies for admin users.
"""
__tablename__ = "admin_sessions"
id = Column(Integer, primary_key=True, index=True)
admin_user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
session_token = Column(String(255), unique=True, nullable=False, index=True)
ip_address = Column(String(45), nullable=False)
user_agent = Column(Text)
login_at = Column(DateTime, nullable=False, index=True)
last_activity_at = Column(DateTime, nullable=False)
logout_at = Column(DateTime, nullable=True)
is_active = Column(Boolean, default=True, index=True)
logout_reason = Column(String(50)) # manual, timeout, forced, suspicious
# Relationships
admin_user = relationship("User", foreign_keys=[admin_user_id])
def __repr__(self):
return f"<AdminSession(id={self.id}, admin_user_id={self.admin_user_id}, is_active={self.is_active})>"
class ApplicationLog(Base, TimestampMixin):
"""
Application-level logs stored in database for critical events.
Stores WARNING, ERROR, and CRITICAL level logs for easy searching,
filtering, and compliance. INFO and DEBUG logs are kept in files only.
"""
__tablename__ = "application_logs"
id = Column(Integer, primary_key=True, index=True)
timestamp = Column(DateTime, nullable=False, index=True)
level = Column(String(20), nullable=False, index=True) # WARNING, ERROR, CRITICAL
logger_name = Column(String(200), nullable=False, index=True)
module = Column(String(200))
function_name = Column(String(100))
line_number = Column(Integer)
message = Column(Text, nullable=False)
exception_type = Column(String(200))
exception_message = Column(Text)
stack_trace = Column(Text)
request_id = Column(String(100), index=True) # For correlating logs
user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True)
store_id = Column(Integer, ForeignKey("stores.id"), nullable=True, index=True)
context = Column(JSON) # Additional context data
# Relationships
user = relationship("User", foreign_keys=[user_id])
store = relationship("Store", foreign_keys=[store_id])
def __repr__(self):
return f"<ApplicationLog(id={self.id}, level='{self.level}', logger='{self.logger_name}')>"
__all__ = [
"AdminAuditLog",
"AdminSetting",
"PlatformAlert",
"AdminSession",
"ApplicationLog",
]