rmi-backend/app/_archive/legacy_2026_07/rmi_dashboard.py
cryptorugmunch 628c1d2a10
Some checks failed
CI / build (push) Failing after 3s
refactor(rmi-backend,audit): mount Wave 3 + archive 136 dead-code files (P2.3)
PHASE 2.3 (AUDIT-2026-Q3.md):

Task 1 — Wire-in Wave 3 (1 router mounted, 2 deferred):
  - app.routers.unified_scanner_router mounted at /api/v2/scanner/* (2 routes:
    POST /api/v2/scanner/token/scan, POST /api/v2/scanner/wallet/scan).
    Refactored prefix from /api/v2 -> /api/v2/scanner to avoid future conflicts
    with the v1 /api/v1/scanner/ stub.
  - app.routers.unified_wallet_scanner DEFERRED (no router APIRouter attribute;
    library module consumed by unified_scanner_router via get_wallet_scanner()).
  - app.routers.admin_extensions DEFERRED (DORMANT per audit; 25 routes at
    /api/v1/admin/* would shadow /api/v1/admin/alerts_webhook).

Task 2 — Archive 136 dead-code files to app/_archive/legacy_2026_07/:
  - 73 routers in app/routers/ (reach graph showed zero reach into mount.py).
  - 63 flat app/*.py (domain modules never imported by live code).
  - 1 file RESTORED post-archive: app/routers/x402_bridge_health.py (caught by
    tests/unit/test_bridge_health.py which directly imports it; reach graph
    considered tests/ only as transitive reach — to be patched in next cycle).

Forced-LIVE (NOT archived per user directive):
  - app/ai_pipeline_v3.py  (3 importers in audit window, importers themselves DEAD)
  - app/splade_bm25.py       (LIVE via app.rag_service)
  - app/wallet_manager_v2.py (LIVE via x402_enforcement, x402_tools, sweep_all, sweep_now)
  - app/crypto_embeddings.py (NOT in audit ARCHIVE list; heavy import graph)

Verification (forward-import closure from mount.py + main.py + factory.py + lifespan.py):
  - imports = 348 app.* modules
  - reached = 194 files reachable from roots
  - archive set = audit_dead (186) - reached - forced_live (4) - test_live (1) = 136
  - Net delta: 136 files moved, 44,932 LOC reduction, 293->295 active routes (+2 from Wave 3)

pyproject.toml updates:
  - setuptools.packages.find: added exclude for app._archive*
  - ruff.extend-exclude: added "app/_archive/"
  - mypy.exclude: added "app/_archive/"

Smoke test: pytest tests/ — 817 passed, 3 pre-existing failures unchanged
(0 new failures; 0 routes lost; all 4 forced-LIVE files still importable).

Restoration: git mv app/_archive/legacy_2026_07/<name>.py <original-path>
and add the import to app/mount.py ROUTER_MODULES.

Refs: AUDIT-2026-Q3.md /home/dev/pry/rmi-final-deadcode-2026-07-06.md
2026-07-06 20:52:31 +02:00

353 lines
14 KiB
Python

"""
RMI TUI Dashboard - Terminal User Interface
===========================================
Interactive CLI dashboard for RMI platform.
Features:
- System status display
- Menu-driven navigation
- Quick commands for common actions
- Live backend status monitoring
"""
import os
import subprocess
import time
from typing import Any
import httpx
from app.core.logging import get_logger
logger = get_logger(__name__)
# Terminal colors
class Colors:
RED = "\033[0;31m"
GREEN = "\033[0;32m"
YELLOW = "\033[1;33m"
BLUE = "\033[0;34m"
PURPLE = "\033[0;35m"
CYAN = "\033[0;36m"
WHITE = "\033[0;37m"
BOLD = "\033[1m"
RESET = "\033[0m"
# ─── UI UTILITIES ──────────────────────────────────────────────────
def clear_screen():
"""Clear terminal screen."""
os.system("clear" if os.name == "posix" else "cls")
def print_header(title: str):
"""Print centered header."""
width = 60
logger.info(f"\n{Colors.BLUE}{'=' * width}{Colors.RESET}")
print(
f"{Colors.BLUE}{Colors.RESET}{Colors.BOLD}{title.center(width - 2)}{Colors.RESET}{Colors.BLUE}{Colors.RESET}"
)
logger.info(f"{Colors.BLUE}{'=' * width}{Colors.RESET}\n")
def print_box(title: str, content: str, color=Colors.WHITE):
"""Print content in a box."""
lines = content.split("\n")
max_len = max(len(l) for l in lines) if lines else 0 # noqa: E741
width = max_len + 4
logger.info(f"\n{color}{'' * width}{Colors.RESET}")
logger.info(f"{color}{Colors.RESET} {Colors.BOLD}{title.center(width - 2)}{Colors.RESET} {color}{Colors.RESET}")
logger.info(f"{color}{'' * width}{Colors.RESET}")
for line in lines:
logger.info(f"{color}{Colors.RESET} {line.ljust(width - 2)} {color}{Colors.RESET}")
logger.info(f"{color}{'' * width}{Colors.RESET}\n")
# ─── STATUS MONITOR ────────────────────────────────────────────────
def get_backend_status(url: str = "http://127.0.0.1:8010") -> dict[str, Any]:
"""Get backend health status."""
try:
response = httpx.get(f"{url}/health", timeout=2)
if response.status_code == 200:
return response.json()
except Exception:
pass
return {"error": "Backend not reachable"}
def get_redis_status() -> dict[str, Any]:
"""Get Redis connection status."""
try:
import redis
r = redis.Redis(host="localhost", port=6379, db=0, socket_timeout=2)
if r.ping():
info = r.info()
return {
"connected": True,
"version": info.get("redis_version", "unknown"),
"memory_used": info.get("used_memory_human", "unknown"),
"connections": info.get("connected_clients", 0),
}
except Exception:
pass
return {"error": "Redis not reachable"}
# ─── DASHBOARD UI ──────────────────────────────────────────────────
class Dashboard:
"""Interactive TUI Dashboard."""
def __init__(self):
self.running = True
self.current_view = "main"
def display_main(self):
"""Display main menu."""
clear_screen()
# Header
logger.info(f"{Colors.CYAN}{Colors.BOLD}")
logger.info("╔════════════════════════════════════════════════════════════╗")
logger.info("║ RMI INTELLIGENCE PLATFORM v2.0.0 ║")
logger.info("╚════════════════════════════════════════════════════════════╝")
logger.info(f"{Colors.RESET}")
# Status
backend = get_backend_status()
redis = get_redis_status()
backend_status = (
f"{Colors.GREEN}● Online{Colors.RESET}"
if backend.get("status") == "ok"
else f"{Colors.RED}● Offline{Colors.RESET}"
)
redis_status = (
f"{Colors.GREEN}● Connected{Colors.RESET}"
if redis.get("connected")
else f"{Colors.RED}● Disconnected{Colors.RESET}"
)
logger.info(f"{Colors.YELLOW}System Status:{Colors.RESET}")
logger.info(f" Backend: {backend_status} | Redis: {redis_status}")
if backend.get("status") == "ok":
logger.info(f" Service: {backend.get('service', 'unknown')}")
logger.info(f" Version: {backend.get('version', 'unknown')}")
logger.info(f" Timestamp: {backend.get('timestamp', 'N/A')}")
logger.info(f"\n{Colors.YELLOW}Available Ports:{Colors.RESET}")
logger.info(" 8010 - Main Backend API")
logger.info(" 6379 - Redis Server")
logger.info(" 22 - SSH (if enabled)")
# Features
logger.info(f"\n{Colors.YELLOW}Built-in Features:{Colors.RESET}")
features = [
("[1] Server Control", "Start/stop/restart backend server"),
("[2] Auth System", "User authentication & OAuth management"),
("[3] Security Intel", "Threat intel & contract scanning"),
("[4] x402 Micropayments", "Micropayment enforcement & tools"),
("[5] Chat Interface", "Direct chat with RMI assistant"),
("[6] Dashboard TUI", "Interactive terminal dashboard"),
("[7] Network Status", "Check all service connectivity"),
("[0] Quit", "Exit to shell"),
]
for key, (name, desc) in enumerate(features):
logger.info(f" {Colors.GREEN}{key}{Colors.RESET}. {Colors.CYAN}{name:<20}{Colors.RESET} - {desc}")
logger.info(f"\n{Colors.PURPLE}Use 'help' for more information{Colors.RESET}\n")
def display_server_control(self):
"""Display server control menu."""
print_header("Server Control")
pid = self._get_backend_pid()
status = "Running" if pid else "Stopped"
logger.info(f" Backend Status: {Colors.GREEN if pid else Colors.RED}{status}{Colors.RESET}")
if pid:
logger.info(f" PID: {pid}")
logger.info("\n Actions:")
logger.info(f" {Colors.GREEN}1{Colors.RESET}. Start Backend")
logger.info(f" {Colors.GREEN}2{Colors.RESET}. Stop Backend")
logger.info(f" {Colors.GREEN}3{Colors.RESET}. Restart Backend")
logger.info(f" {Colors.GREEN}0{Colors.RESET}. Back")
choice = input("\n Select: ").strip()
if choice == "1":
self._start_backend()
elif choice == "2":
self._stop_backend()
elif choice == "3":
self._restart_backend()
def _get_backend_pid(self) -> int | None:
"""Get backend process ID."""
try:
result = subprocess.run(["pgrep", "-f", "uvicorn main:app"], capture_output=True, text=True, timeout=5)
if result.stdout.strip():
return int(result.stdout.strip())
except Exception:
pass
return None
def _start_backend(self):
"""Start backend server."""
logger.info("\n{Colors.YELLOW}Starting backend...{Colors.RESET}")
try:
subprocess.Popen(
["python3", "-m", "uvicorn", "main:app", "--host", "127.0.0.1", "--port", "8010"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
start_new_session=True,
)
time.sleep(3)
logger.info(f"{Colors.GREEN}Backend started!{Colors.RESET}")
except Exception as e:
logger.warning(f"{Colors.RED}Error starting backend: {e}{Colors.RESET}")
def _stop_backend(self):
"""Stop backend server."""
pid = self._get_backend_pid()
if pid:
try:
os.kill(pid, 15)
logger.info(f"{Colors.GREEN}Backend stopped (PID: {pid}){Colors.RESET}")
except Exception as e:
logger.warning(f"{Colors.RED}Error stopping backend: {e}{Colors.RESET}")
def _restart_backend(self):
"""Restart backend server."""
self._stop_backend()
time.sleep(1)
self._start_backend()
def display_auth_system(self):
"""Display auth system info."""
print_header("Authentication System")
logger.info(f" {Colors.CYAN}OAuth Providers:{Colors.RESET}")
logger.info(" • Email + Password")
logger.info(" • Google")
logger.info(" • Telegram")
logger.info(" • GitHub")
logger.info(" • Wallet Signature (EIP-4361)")
logger.info(f"\n {Colors.CYAN}Features:{Colors.RESET}")
logger.info(" • Session management (JWT)")
logger.info(" • Rate limiting per user")
logger.info(" • x402 micropayment enforcement")
logger.info(f"\n {Colors.CYAN}Endpoints:{Colors.RESET}")
logger.info(" POST /api/v1/auth/register - Register new user")
logger.info(" POST /api/v1/auth/login - Login user")
logger.info(" GET /api/v1/auth/status - Get current session")
input(f"\n{Colors.PURPLE}Press Enter to return...{Colors.RESET}")
def display_security_intel(self):
"""Display security intel info."""
print_header("Security Intelligence")
logger.info(f" {Colors.CYAN}Modules:{Colors.RESET}")
logger.info(" • Slither - Static analysis")
logger.info(" • Mythril - Symbolic execution")
logger.info(" • OFAC Sanctions - Blocklist")
logger.info(" • Threat Intel - Risk scoring")
logger.info(f"\n {Colors.CYAN}Contract Scanning:{Colors.RESET}")
logger.info(" • Reentrancy detection")
logger.info(" • Integer overflow/underflow")
logger.info(" • Unchecked calls")
logger.info(" • DAO patterns")
input(f"\n{Colors.PURPLE}Press Enter to return...{Colors.RESET}")
def display_x402_menu(self):
"""Display x402 micropayments info."""
print_header("x402 Micropayments")
logger.info(f" {Colors.CYAN}Features:{Colors.RESET}")
logger.info(" • Micropayment enforcement")
logger.info(" • Rate-based pricing")
logger.info(" • Forensic analysis")
logger.info(" • Redis-backed tracking")
logger.info(f"\n {Colors.CYAN}Endpoints:{Colors.RESET}")
logger.info(" GET /api/v1/x402/tools - Available tools catalog")
logger.info(" GET /api/v1/x402/status - Payment status")
logger.info(" POST /api/v1/x402/enforce - Enforce micropayment")
input(f"\n{Colors.PURPLE}Press Enter to return...{Colors.RESET}")
def display_chat(self):
"""Launch chat interface."""
print_header("Chat Interface")
logger.info("\n{Colors.YELLOW}Direct chat with RMI assistant{Colors.RESET}")
logger.info("\n{Colors.RED}Note:{Colors.RESET} This launches the system shell")
input(f"\n{Colors.PURPLE}Press Enter to return...{Colors.RESET}")
def display_network_status(self):
"""Display network connectivity status."""
print_header("Network Status")
tests = [
("Local Backend", "http://127.0.0.1:8010", "/health"),
("Redis", "localhost", None),
("Ethereum RPC", "https://ethereum-rpc.publicnode.com", None),
("Base RPC", "https://base-rpc.publicnode.com", None),
]
for name, url, path in tests:
try:
full_url = f"{url}{path}" if path else url
response = httpx.get(full_url, timeout=3)
status = f"{Colors.GREEN}✓ OK{Colors.RESET} ({response.status_code})"
except Exception:
status = f"{Colors.RED}✗ Failed{Colors.RESET}"
logger.info(f" {name:<20} {status}")
logger.info()
input(f"{Colors.PURPLE}Press Enter to return...{Colors.RESET}")
def run(self):
"""Main dashboard loop."""
while self.running:
self.display_main()
choice = input("Select an option: ").strip().lower()
if choice == "0":
self.running = False
elif choice == "1":
self.display_server_control()
elif choice == "2":
self.display_auth_system()
elif choice == "3":
self.display_security_intel()
elif choice == "4":
self.display_x402_menu()
elif choice == "5":
self.display_chat()
elif choice == "6":
logger.info("{TUI already running}")
elif choice == "7":
self.display_network_status()
elif choice in ["help", "?"]:
logger.info(f"{Colors.YELLOW}Commands:{Colors.RESET}")
logger.info(" help - Show this help")
logger.info(" clear - Clear screen")
logger.info(" quit - Exit dashboard")
elif choice == "clear":
clear_screen()
elif choice in ["quit", "exit"]:
self.running = False
else:
logger.info(f"{Colors.RED}Invalid option{Colors.RESET}")
# ─── SINGLETON LAUNCHER ────────────────────────────────────────────
def launch_dashboard():
"""Launch the interactive dashboard."""
try:
dashboard = Dashboard()
dashboard.run()
except KeyboardInterrupt:
pass
except Exception as e:
logger.warning(f"{Colors.RED}Dashboard error: {e}{Colors.RESET}")
# ─── CLI ENTRY POINT ───────────────────────────────────────────────
if __name__ == "__main__":
launch_dashboard()