avl_console/lib.rs
1//! # AVL Console - Developer Portal & Web Dashboard
2//!
3//! **World-class developer portal** for AVL Cloud Platform.
4//!
5//! ## Features
6//!
7//! - **Dashboard**: Real-time resource overview with WebSocket updates
8//! - **AvilaDB Explorer**: Interactive query editor with syntax highlighting
9//! - **Storage Browser**: Full S3-compatible file management
10//! - **Observability**: Metrics, logs, traces with advanced filtering
11//! - **Billing**: Cost tracking, usage analytics, budget alerts
12//! - **API Explorer**: Interactive API testing with OpenAPI specs
13//! - **User Management**: Teams, permissions, audit logs
14//!
15//! ## Architecture
16//!
17//! ```text
18//! ┌─────────────────────────────────────────────────┐
19//! │ AVL Console Frontend │
20//! │ (Server-Side Rendered + Real-Time WebSocket) │
21//! └─────────────────────────────────────────────────┘
22//! ↓
23//! ┌─────────────────────────────────────────────────┐
24//! │ Axum REST API Layer │
25//! │ (Authentication, Rate Limiting, CORS) │
26//! └─────────────────────────────────────────────────┘
27//! ↓
28//! ┌──────────────┬──────────────┬──────────────────┐
29//! │ AvilaDB │ Storage │ Observability │
30//! │ Explorer │ Browser │ Dashboard │
31//! └──────────────┴──────────────┴──────────────────┘
32//! ```
33//!
34//! ## Quick Start
35//!
36//! ```rust,no_run
37//! use avl_console::{Console, ConsoleConfig};
38//! use std::net::SocketAddr;
39//!
40//! #[tokio::main]
41//! async fn main() -> anyhow::Result<()> {
42//! let config = ConsoleConfig::from_env()?;
43//! let console = Console::new(config).await?;
44//! let addr: SocketAddr = "127.0.0.1:8080".parse()?;
45//!
46//! console.serve(addr).await?;
47//! Ok(())
48//! }
49//! ```
50
51pub mod api;
52pub mod auth;
53pub mod config;
54pub mod dashboard;
55pub mod database;
56pub mod error;
57pub mod middleware;
58pub mod observability;
59pub mod storage;
60pub mod billing;
61pub mod templates;
62pub mod websocket;
63pub mod state;
64pub mod query_builder;
65pub mod monitoring;
66pub mod teams;
67pub mod ai_assistant;
68pub mod ai_engine;
69
70use std::net::SocketAddr;
71use std::sync::Arc;
72
73use axum::Router;
74use tower::ServiceBuilder;
75use tower_http::{
76 services::ServeDir,
77 trace::TraceLayer,
78 compression::CompressionLayer,
79 cors::CorsLayer,
80};
81
82pub use config::ConsoleConfig;
83pub use error::{ConsoleError, Result};
84pub use state::AppState;
85
86/// AVL Console - Main application structure
87///
88/// Manages the entire console lifecycle including:
89/// - HTTP server with Axum
90/// - WebSocket connections for real-time updates
91/// - Authentication and authorization
92/// - Resource management (databases, storage, etc.)
93#[derive(Clone)]
94pub struct Console {
95 state: Arc<AppState>,
96 config: ConsoleConfig,
97}
98
99impl Console {
100 /// Create a new Console instance
101 ///
102 /// # Example
103 ///
104 /// ```rust,no_run
105 /// # use avl_console::{Console, ConsoleConfig};
106 /// # async fn example() -> anyhow::Result<()> {
107 /// let config = ConsoleConfig::default();
108 /// let console = Console::new(config).await?;
109 /// # Ok(())
110 /// # }
111 /// ```
112 pub async fn new(config: ConsoleConfig) -> Result<Self> {
113 let state = Arc::new(AppState::new(&config).await?);
114
115 Ok(Self { state, config })
116 }
117
118 /// Build the Axum router with all routes and middleware
119 pub fn router(&self) -> Router {
120 Router::new()
121 // API routes
122 .nest("/api", api::routes(self.state.clone()))
123 // Dashboard routes
124 .nest("/dashboard", dashboard::routes(self.state.clone()))
125 // Database explorer
126 .nest("/databases", database::routes(self.state.clone()))
127 // Storage browser
128 .nest("/storage", storage::routes(self.state.clone()))
129 // Observability
130 .nest("/observability", observability::routes(self.state.clone()))
131 // Billing
132 .nest("/billing", billing::routes(self.state.clone()))
133 // Query Builder
134 .nest("/query-builder", query_builder::router(self.state.clone()))
135 // Advanced Monitoring
136 .nest("/monitoring", monitoring::router(self.state.clone()))
137 // Team Management & RBAC
138 .nest("/teams", teams::router(self.state.clone()))
139 // AI Assistant
140 .nest("/ai-assistant", ai_assistant::router(self.state.clone()))
141 // WebSocket endpoint
142 .nest("/ws", websocket::routes(self.state.clone()))
143 // Static files
144 .nest_service("/static", ServeDir::new("static"))
145 // Root redirect to dashboard
146 .fallback(dashboard::index)
147 .layer(
148 ServiceBuilder::new()
149 .layer(TraceLayer::new_for_http())
150 .layer(CompressionLayer::new())
151 .layer(CorsLayer::permissive())
152 .layer(middleware::auth::AuthLayer::new(self.state.clone()))
153 .layer(middleware::rate_limit::RateLimitLayer::new())
154 )
155 }
156
157 /// Start the console server
158 ///
159 /// # Example
160 ///
161 /// ```rust,no_run
162 /// # use avl_console::{Console, ConsoleConfig};
163 /// # use std::net::SocketAddr;
164 /// # async fn example() -> anyhow::Result<()> {
165 /// let console = Console::new(ConsoleConfig::default()).await?;
166 /// let addr: SocketAddr = "127.0.0.1:8080".parse()?;
167 /// console.serve(addr).await?;
168 /// # Ok(())
169 /// # }
170 /// ```
171 pub async fn serve(self, addr: impl Into<SocketAddr>) -> Result<()> {
172 let addr = addr.into();
173 let router = self.router();
174
175 tracing::info!("🖥️ AVL Console starting on http://{}", addr);
176 tracing::info!("📊 Dashboard: http://{}/dashboard", addr);
177 tracing::info!("🗄️ AvilaDB Explorer: http://{}/databases", addr);
178 tracing::info!("💾 Storage Browser: http://{}/storage", addr);
179 tracing::info!("📈 Observability: http://{}/observability", addr);
180 tracing::info!("🎨 Query Builder: http://{}/query-builder", addr);
181 tracing::info!("🔬 Advanced Monitoring: http://{}/monitoring", addr);
182 tracing::info!("👥 Team Management: http://{}/teams", addr);
183 tracing::info!("🤖 AI Assistant: http://{}/ai-assistant", addr);
184
185 let listener = tokio::net::TcpListener::bind(addr)
186 .await
187 .map_err(|e| ConsoleError::Server(e.to_string()))?;
188
189 axum::serve(listener, router)
190 .await
191 .map_err(|e| ConsoleError::Server(e.to_string()))?;
192
193 Ok(())
194 }
195
196 /// Get reference to application state
197 pub fn state(&self) -> &Arc<AppState> {
198 &self.state
199 }
200
201 /// Get configuration
202 pub fn config(&self) -> &ConsoleConfig {
203 &self.config
204 }
205}
206
207#[cfg(test)]
208mod tests {
209 use super::*;
210
211 #[tokio::test]
212 async fn test_console_creation() {
213 let config = ConsoleConfig::default();
214 let console = Console::new(config).await;
215 assert!(console.is_ok());
216 }
217}