Database & Migrations: - Add application_logs table migration for hybrid cloud logging - Add companies table migration and restructure vendor relationships Logging System: - Implement hybrid logging system (database + file) - Add log_service for centralized log management - Create admin logs page with filtering and viewing capabilities - Add init_log_settings.py script for log configuration - Enhance core logging with database integration Marketplace Integration: - Add marketplace admin page with product management - Create marketplace vendor page with product listings - Implement marketplace.js for both admin and vendor interfaces - Add marketplace integration documentation Admin Enhancements: - Add imports management page and functionality - Create settings page for admin configuration - Add vendor themes management page - Enhance vendor detail and edit pages - Improve code quality dashboard and violation details - Add logs viewing and management - Update icons guide and shared icon system Architecture & Documentation: - Document frontend structure and component architecture - Document models structure and relationships - Add vendor-in-token architecture documentation - Add vendor RBAC (role-based access control) documentation - Document marketplace integration patterns - Update architecture patterns documentation Infrastructure: - Add platform static files structure (css, img, js) - Move architecture_scan.py to proper models location - Update model imports and registrations - Enhance exception handling - Update dependency injection patterns UI/UX: - Improve vendor edit interface - Update admin user interface - Enhance page templates documentation - Add vendor marketplace interface
180 lines
6.1 KiB
Python
180 lines
6.1 KiB
Python
"""
|
|
Architecture Scan Models
|
|
Database models for tracking code quality scans and violations
|
|
"""
|
|
|
|
from sqlalchemy import (
|
|
JSON,
|
|
Boolean,
|
|
Column,
|
|
DateTime,
|
|
Float,
|
|
ForeignKey,
|
|
Integer,
|
|
String,
|
|
Text,
|
|
)
|
|
from sqlalchemy.orm import relationship
|
|
from sqlalchemy.sql import func
|
|
|
|
from app.core.database import Base
|
|
|
|
|
|
class ArchitectureScan(Base):
|
|
"""Represents a single run of the architecture validator"""
|
|
|
|
__tablename__ = "architecture_scans"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
timestamp = Column(
|
|
DateTime(timezone=True), server_default=func.now(), nullable=False, index=True
|
|
)
|
|
total_files = Column(Integer, default=0)
|
|
total_violations = Column(Integer, default=0)
|
|
errors = Column(Integer, default=0)
|
|
warnings = Column(Integer, default=0)
|
|
duration_seconds = Column(Float, default=0.0)
|
|
triggered_by = Column(String(100)) # 'manual', 'scheduled', 'ci/cd'
|
|
git_commit_hash = Column(String(40))
|
|
|
|
# Relationship to violations
|
|
violations = relationship(
|
|
"ArchitectureViolation", back_populates="scan", cascade="all, delete-orphan"
|
|
)
|
|
|
|
def __repr__(self):
|
|
return f"<ArchitectureScan(id={self.id}, violations={self.total_violations}, errors={self.errors})>"
|
|
|
|
|
|
class ArchitectureViolation(Base):
|
|
"""Represents a single architectural violation found during a scan"""
|
|
|
|
__tablename__ = "architecture_violations"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
scan_id = Column(
|
|
Integer, ForeignKey("architecture_scans.id"), nullable=False, index=True
|
|
)
|
|
rule_id = Column(String(20), nullable=False, index=True) # e.g., 'API-001'
|
|
rule_name = Column(String(200), nullable=False)
|
|
severity = Column(
|
|
String(10), nullable=False, index=True
|
|
) # 'error', 'warning', 'info'
|
|
file_path = Column(String(500), nullable=False, index=True)
|
|
line_number = Column(Integer, nullable=False)
|
|
message = Column(Text, nullable=False)
|
|
context = Column(Text) # Code snippet
|
|
suggestion = Column(Text)
|
|
status = Column(
|
|
String(20), default="open", index=True
|
|
) # 'open', 'assigned', 'resolved', 'ignored', 'technical_debt'
|
|
assigned_to = Column(Integer, ForeignKey("users.id"))
|
|
resolved_at = Column(DateTime(timezone=True))
|
|
resolved_by = Column(Integer, ForeignKey("users.id"))
|
|
resolution_note = Column(Text)
|
|
created_at = Column(
|
|
DateTime(timezone=True), server_default=func.now(), nullable=False
|
|
)
|
|
|
|
# Relationships
|
|
scan = relationship("ArchitectureScan", back_populates="violations")
|
|
assigned_user = relationship(
|
|
"User", foreign_keys=[assigned_to], backref="assigned_violations"
|
|
)
|
|
resolver = relationship(
|
|
"User", foreign_keys=[resolved_by], backref="resolved_violations"
|
|
)
|
|
assignments = relationship(
|
|
"ViolationAssignment", back_populates="violation", cascade="all, delete-orphan"
|
|
)
|
|
comments = relationship(
|
|
"ViolationComment", back_populates="violation", cascade="all, delete-orphan"
|
|
)
|
|
|
|
def __repr__(self):
|
|
return f"<ArchitectureViolation(id={self.id}, rule={self.rule_id}, file={self.file_path}:{self.line_number})>"
|
|
|
|
|
|
class ArchitectureRule(Base):
|
|
"""Architecture rules configuration (from YAML with database overrides)"""
|
|
|
|
__tablename__ = "architecture_rules"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
rule_id = Column(
|
|
String(20), unique=True, nullable=False, index=True
|
|
) # e.g., 'API-001'
|
|
category = Column(
|
|
String(50), nullable=False
|
|
) # 'api_endpoint', 'service_layer', etc.
|
|
name = Column(String(200), nullable=False)
|
|
description = Column(Text)
|
|
severity = Column(String(10), nullable=False) # Can override default from YAML
|
|
enabled = Column(Boolean, default=True, nullable=False)
|
|
custom_config = Column(JSON) # For rule-specific settings
|
|
created_at = Column(
|
|
DateTime(timezone=True), server_default=func.now(), nullable=False
|
|
)
|
|
updated_at = Column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
onupdate=func.now(),
|
|
nullable=False,
|
|
)
|
|
|
|
def __repr__(self):
|
|
return f"<ArchitectureRule(id={self.rule_id}, name={self.name}, enabled={self.enabled})>"
|
|
|
|
|
|
class ViolationAssignment(Base):
|
|
"""Tracks assignment of violations to developers"""
|
|
|
|
__tablename__ = "violation_assignments"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
violation_id = Column(
|
|
Integer, ForeignKey("architecture_violations.id"), nullable=False, index=True
|
|
)
|
|
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
|
assigned_at = Column(
|
|
DateTime(timezone=True), server_default=func.now(), nullable=False
|
|
)
|
|
assigned_by = Column(Integer, ForeignKey("users.id"))
|
|
due_date = Column(DateTime(timezone=True))
|
|
priority = Column(
|
|
String(10), default="medium"
|
|
) # 'low', 'medium', 'high', 'critical'
|
|
|
|
# Relationships
|
|
violation = relationship("ArchitectureViolation", back_populates="assignments")
|
|
user = relationship("User", foreign_keys=[user_id], backref="violation_assignments")
|
|
assigner = relationship(
|
|
"User", foreign_keys=[assigned_by], backref="assigned_by_me"
|
|
)
|
|
|
|
def __repr__(self):
|
|
return f"<ViolationAssignment(id={self.id}, violation_id={self.violation_id}, user_id={self.user_id})>"
|
|
|
|
|
|
class ViolationComment(Base):
|
|
"""Comments on violations for collaboration"""
|
|
|
|
__tablename__ = "violation_comments"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
violation_id = Column(
|
|
Integer, ForeignKey("architecture_violations.id"), nullable=False, index=True
|
|
)
|
|
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
|
comment = Column(Text, nullable=False)
|
|
created_at = Column(
|
|
DateTime(timezone=True), server_default=func.now(), nullable=False
|
|
)
|
|
|
|
# Relationships
|
|
violation = relationship("ArchitectureViolation", back_populates="comments")
|
|
user = relationship("User", backref="violation_comments")
|
|
|
|
def __repr__(self):
|
|
return f"<ViolationComment(id={self.id}, violation_id={self.violation_id}, user_id={self.user_id})>"
|