mockforge_ui/
lib.rs

1//! Pillars: [DevX]
2//!
3//! # MockForge UI
4//!
5//! Web-based admin interface for managing mock servers.
6
7pub mod audit;
8pub mod auth;
9pub mod handlers;
10pub mod rbac;
11pub mod routes;
12// Templates module removed; static assets in `static/` are the single source of truth
13pub mod models;
14pub mod prometheus_client;
15pub mod time_travel_handlers;
16
17pub use models::{RequestLog, RouteInfo, ServerStatus, SystemInfo};
18pub use routes::create_admin_router;
19
20use std::net::SocketAddr;
21
22/// Start the admin UI server
23///
24/// # Arguments
25/// * `addr` - Address to bind the admin server to
26/// * `http_server_addr` - HTTP server address
27/// * `ws_server_addr` - WebSocket server address
28/// * `grpc_server_addr` - gRPC server address
29/// * `graphql_server_addr` - GraphQL server address
30/// * `api_enabled` - Whether API endpoints are enabled
31/// * `prometheus_url` - Prometheus metrics URL
32/// * `chaos_api_state` - Optional chaos API state for hot-reload support
33/// * `latency_injector` - Optional latency injector for hot-reload support
34/// * `mockai` - Optional MockAI instance for hot-reload support
35/// * `continuum_config` - Optional Reality Continuum configuration
36/// * `virtual_clock` - Optional virtual clock for time-based progression
37pub async fn start_admin_server(
38    addr: SocketAddr,
39    http_server_addr: Option<SocketAddr>,
40    ws_server_addr: Option<SocketAddr>,
41    grpc_server_addr: Option<SocketAddr>,
42    graphql_server_addr: Option<SocketAddr>,
43    api_enabled: bool,
44    prometheus_url: String,
45    chaos_api_state: Option<std::sync::Arc<mockforge_chaos::api::ChaosApiState>>,
46    latency_injector: Option<
47        std::sync::Arc<tokio::sync::RwLock<mockforge_core::latency::LatencyInjector>>,
48    >,
49    mockai: Option<
50        std::sync::Arc<tokio::sync::RwLock<mockforge_core::intelligent_behavior::MockAI>>,
51    >,
52    continuum_config: Option<mockforge_core::ContinuumConfig>,
53    virtual_clock: Option<std::sync::Arc<mockforge_core::VirtualClock>>,
54) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
55    let app = create_admin_router(
56        http_server_addr,
57        ws_server_addr,
58        grpc_server_addr,
59        graphql_server_addr,
60        api_enabled,
61        addr.port(),
62        prometheus_url,
63        chaos_api_state,
64        latency_injector,
65        mockai,
66        continuum_config,
67        virtual_clock,
68    );
69
70    tracing::info!("Starting MockForge Admin UI on {}", addr);
71
72    let listener = tokio::net::TcpListener::bind(addr).await.map_err(|e| {
73        format!(
74            "Failed to bind Admin UI server to port {}: {}\n\
75             Hint: The port may already be in use. Try using a different port with --admin-port or check if another process is using this port with: lsof -i :{} or netstat -tulpn | grep {}",
76            addr.port(), e, addr.port(), addr.port()
77        )
78    })?;
79
80    axum::serve(listener, app).await?;
81
82    Ok(())
83}
84
85/// Get React UI HTML content
86pub fn get_admin_html() -> &'static str {
87    include_str!("../ui/dist/index.html")
88}
89
90/// Get React UI CSS content
91pub fn get_admin_css() -> &'static str {
92    include_str!("../ui/dist/assets/index.css")
93}
94
95/// Get React UI JavaScript content
96pub fn get_admin_js() -> &'static str {
97    include_str!("../ui/dist/assets/index.js")
98}
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103
104    #[test]
105    fn test_get_admin_html() {
106        let html = get_admin_html();
107        assert!(!html.is_empty());
108        assert!(html.contains("<!DOCTYPE html>") || html.contains("<html"));
109    }
110
111    #[test]
112    fn test_get_admin_css() {
113        let css = get_admin_css();
114        assert!(!css.is_empty());
115    }
116
117    #[test]
118    fn test_get_admin_js() {
119        let js = get_admin_js();
120        assert!(!js.is_empty());
121    }
122}