""" Module 8: Generate Architecture Diagram System architecture visualization. """ import os, sys sys.path.insert(0, '/app/fraud_detection') import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.patches as mpatches from matplotlib.patches import FancyBboxPatch, FancyArrowPatch import numpy as np from config import FIGURES_DIR, FIG_DPI, FIG_BG def draw_architecture(): """Draw the system architecture diagram.""" fig, ax = plt.subplots(1, 1, figsize=(16, 10), facecolor=FIG_BG) ax.set_xlim(0, 16) ax.set_ylim(0, 10) ax.axis('off') # Colors c_input = '#3498db' c_process = '#2ecc71' c_model = '#e74c3c' c_output = '#f39c12' c_storage = '#9b59b6' def box(x, y, w, h, text, color, fontsize=9): rect = FancyBboxPatch((x, y), w, h, boxstyle="round,pad=0.1", facecolor=color, edgecolor='black', linewidth=1.5, alpha=0.85) ax.add_patch(rect) ax.text(x + w/2, y + h/2, text, ha='center', va='center', fontsize=fontsize, fontweight='bold', color='white', multialignment='center') def arrow(x1, y1, x2, y2): ax.annotate('', xy=(x2, y2), xytext=(x1, y1), arrowprops=dict(arrowstyle='->', color='black', lw=2)) # Title ax.text(8, 9.5, 'Fraud Detection System Architecture', ha='center', fontsize=16, fontweight='bold', color='#2c3e50') # Layer 1: Data Input box(0.5, 7.5, 3, 1, 'Transaction\nStream', c_input, 10) box(4, 7.5, 3, 1, 'Feature\nEngineering\n(12 features)', c_process, 9) box(7.5, 7.5, 3, 1, 'RobustScaler\n(Fit on Train)', c_process, 9) arrow(3.5, 8, 4, 8) arrow(7, 8, 7.5, 8) # Layer 2: Models box(0.5, 5, 2.2, 1.2, 'Logistic\nRegression', c_model, 8) box(3, 5, 2.2, 1.2, 'Random\nForest', c_model, 8) box(5.5, 5, 2.2, 1.2, 'XGBoost\n(Best)', c_model, 8) box(8, 5, 2.2, 1.2, 'LightGBM', c_model, 8) box(10.5, 5, 2.2, 1.2, 'MLP\nNeural Net', c_model, 8) box(13, 5, 2.5, 1.2, 'Autoencoder\n(Anomaly)', c_model, 8) # Arrows from preprocessing to models for x in [1.6, 4.1, 6.6, 9.1, 11.6, 14.25]: arrow(9, 7.5, x, 6.2) # Layer 3: Ensemble & Optimization box(3, 2.8, 4, 1.2, 'Voting Ensemble\n(XGB + LGBM + RF)', c_output, 10) box(8, 2.8, 4, 1.2, 'Optuna Tuning\n(Hyperparameter Opt)', c_storage, 9) arrow(5, 5, 5, 4) arrow(10, 5, 10, 4) arrow(8, 3.4, 7, 3.4) # Layer 4: Output box(3, 0.5, 4, 1.5, 'FastAPI\nPOST /predict\n< 10ms latency', c_input, 9) box(8, 0.5, 4, 1.5, 'Decision\nFraud Prob + Risk Level\n+ Top Risk Factors', c_output, 9) arrow(5, 2.8, 5, 2) arrow(7, 1.25, 8, 1.25) # Monitoring box box(12.5, 7.5, 3, 1, 'Monitoring\nDrift Detection\nRetraining', c_storage, 9) arrow(10.5, 8, 12.5, 8) # SHAP/LIME box(12.5, 2.8, 3, 1.2, 'Explainability\nSHAP + LIME', c_process, 9) arrow(12, 5, 14, 4) plt.tight_layout() plt.savefig(os.path.join(FIGURES_DIR, "architecture_diagram.png"), dpi=FIG_DPI, bbox_inches='tight', facecolor=FIG_BG) plt.savefig(os.path.join(FIGURES_DIR, "architecture_diagram.pdf"), bbox_inches='tight', facecolor=FIG_BG) plt.close() print("Saved: architecture_diagram.png/pdf") if __name__ == "__main__": draw_architecture()