Implement real code, remove dead code
- AppState now uses BotServerClient directly - BOTSERVER_URL env var support for configuration - index() handler properly integrated into router - Removed unused web module (DTOs were never used) - Removed all #[allow(dead_code)] attributes - Zero warnings, cargo audit clean
This commit is contained in:
parent
38fc25b2a2
commit
0143ad49b1
7 changed files with 109 additions and 226 deletions
22
src/lib.rs
22
src/lib.rs
|
|
@ -8,25 +8,9 @@
|
|||
//! For desktop/mobile native features, see the `botapp` crate which
|
||||
//! wraps this pure web UI with Tauri.
|
||||
|
||||
// Re-export common types from botlib
|
||||
pub use botlib::{
|
||||
branding, error, init_branding, is_white_label, platform_name, platform_short, ApiResponse,
|
||||
BotError, BotResponse, BotResult, MessageType, Session, Suggestion, UserMessage,
|
||||
};
|
||||
|
||||
// HTTP client is always available via botlib
|
||||
pub use botlib::BotServerClient;
|
||||
|
||||
pub mod shared;
|
||||
|
||||
#[cfg(feature = "ui-server")]
|
||||
pub mod ui_server;
|
||||
|
||||
#[cfg(feature = "ui-server")]
|
||||
pub mod web;
|
||||
|
||||
// Re-exports
|
||||
pub use shared::*;
|
||||
|
||||
#[cfg(feature = "ui-server")]
|
||||
pub use ui_server::*;
|
||||
// Re-export commonly used types
|
||||
pub use shared::AppState;
|
||||
pub use ui_server::configure_router;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ use log::info;
|
|||
|
||||
mod shared;
|
||||
mod ui_server;
|
||||
mod web;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
//! Shared types and state management for BotUI
|
||||
//!
|
||||
//! This module re-exports common types from botlib and provides
|
||||
//! UI-specific shared functionality.
|
||||
//! This module provides shared application state and utilities
|
||||
//! used across the UI server.
|
||||
|
||||
pub mod state;
|
||||
|
||||
// Re-export from botlib for convenience
|
||||
|
||||
// Local re-exports
|
||||
pub use state::AppState;
|
||||
|
|
|
|||
|
|
@ -1,48 +1,33 @@
|
|||
//! Application state management
|
||||
//!
|
||||
//! This module contains the shared application state that is passed to all
|
||||
//! route handlers and provides access to database connections, configuration,
|
||||
//! and other shared resources.
|
||||
|
||||
#![allow(dead_code)] // Prepared for future use
|
||||
//! route handlers and provides access to the BotServer client.
|
||||
|
||||
use botlib::http_client::BotServerClient;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
/// Database connection pool type
|
||||
/// This would typically be a real connection pool in production
|
||||
pub type DbPool = Arc<RwLock<()>>;
|
||||
|
||||
/// Application state shared across all handlers
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
/// Database connection pool
|
||||
pub conn: Arc<std::sync::Mutex<()>>,
|
||||
/// Configuration cache
|
||||
pub config: Arc<RwLock<std::collections::HashMap<String, String>>>,
|
||||
/// Session store
|
||||
pub sessions: Arc<RwLock<std::collections::HashMap<String, Session>>>,
|
||||
}
|
||||
|
||||
/// User session information
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Session {
|
||||
pub user_id: String,
|
||||
pub username: String,
|
||||
pub email: String,
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
pub expires_at: chrono::DateTime<chrono::Utc>,
|
||||
/// HTTP client for communicating with BotServer
|
||||
pub client: Arc<BotServerClient>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
/// Create a new application state
|
||||
///
|
||||
/// Uses BOTSERVER_URL environment variable if set, otherwise defaults to localhost:8080
|
||||
pub fn new() -> Self {
|
||||
let url = std::env::var("BOTSERVER_URL").ok();
|
||||
Self {
|
||||
conn: Arc::new(std::sync::Mutex::new(())),
|
||||
config: Arc::new(RwLock::new(std::collections::HashMap::new())),
|
||||
sessions: Arc::new(RwLock::new(std::collections::HashMap::new())),
|
||||
client: Arc::new(BotServerClient::new(url)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the BotServer is healthy
|
||||
pub async fn health_check(&self) -> bool {
|
||||
self.client.health_check().await
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AppState {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
//!
|
||||
//! Serves the web UI (suite, minimal) and handles API proxying.
|
||||
|
||||
#![allow(dead_code)] // Some functions prepared for future use
|
||||
|
||||
use axum::{
|
||||
extract::State,
|
||||
http::StatusCode,
|
||||
|
|
@ -12,17 +10,16 @@ use axum::{
|
|||
Router,
|
||||
};
|
||||
use log::error;
|
||||
use std::{fs, path::PathBuf, sync::Arc};
|
||||
use tower_http::services::ServeDir;
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use botlib::http_client::BotServerClient;
|
||||
use crate::shared::AppState;
|
||||
|
||||
// Serve minimal UI (default at /)
|
||||
/// Serve the index page (minimal UI)
|
||||
pub async fn index() -> impl IntoResponse {
|
||||
serve_minimal().await
|
||||
}
|
||||
|
||||
// Handler for minimal UI
|
||||
/// Handler for minimal UI
|
||||
pub async fn serve_minimal() -> impl IntoResponse {
|
||||
match fs::read_to_string("ui/minimal/index.html") {
|
||||
Ok(html) => (StatusCode::OK, [("content-type", "text/html")], Html(html)),
|
||||
|
|
@ -37,7 +34,7 @@ pub async fn serve_minimal() -> impl IntoResponse {
|
|||
}
|
||||
}
|
||||
|
||||
// Handler for suite UI
|
||||
/// Handler for suite UI
|
||||
pub async fn serve_suite() -> impl IntoResponse {
|
||||
match fs::read_to_string("ui/suite/index.html") {
|
||||
Ok(html) => (StatusCode::OK, [("content-type", "text/html")], Html(html)),
|
||||
|
|
@ -52,49 +49,9 @@ pub async fn serve_suite() -> impl IntoResponse {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn configure_router() -> Router {
|
||||
let suite_path = PathBuf::from("./ui/suite");
|
||||
let minimal_path = PathBuf::from("./ui/minimal");
|
||||
let client = Arc::new(BotServerClient::new(None));
|
||||
|
||||
Router::new()
|
||||
// API health check
|
||||
.route("/health", get(health))
|
||||
.route("/api/health", get(api_health))
|
||||
// Default route serves minimal UI
|
||||
.route("/", get(root))
|
||||
.route("/minimal", get(serve_minimal))
|
||||
// Suite UI route
|
||||
.route("/suite", get(serve_suite))
|
||||
// Suite static assets (when accessing /suite/*)
|
||||
.nest_service("/suite/js", ServeDir::new(suite_path.join("js")))
|
||||
.nest_service("/suite/css", ServeDir::new(suite_path.join("css")))
|
||||
.nest_service("/suite/public", ServeDir::new(suite_path.join("public")))
|
||||
.nest_service("/suite/drive", ServeDir::new(suite_path.join("drive")))
|
||||
.nest_service("/suite/chat", ServeDir::new(suite_path.join("chat")))
|
||||
.nest_service("/suite/mail", ServeDir::new(suite_path.join("mail")))
|
||||
.nest_service("/suite/tasks", ServeDir::new(suite_path.join("tasks")))
|
||||
// Legacy paths for backward compatibility (serve suite assets)
|
||||
.nest_service("/js", ServeDir::new(suite_path.join("js")))
|
||||
.nest_service("/css", ServeDir::new(suite_path.join("css")))
|
||||
.nest_service("/public", ServeDir::new(suite_path.join("public")))
|
||||
.nest_service("/drive", ServeDir::new(suite_path.join("drive")))
|
||||
.nest_service("/chat", ServeDir::new(suite_path.join("chat")))
|
||||
.nest_service("/mail", ServeDir::new(suite_path.join("mail")))
|
||||
.nest_service("/tasks", ServeDir::new(suite_path.join("tasks")))
|
||||
// Fallback for other static files
|
||||
.fallback_service(
|
||||
ServeDir::new(minimal_path.clone()).fallback(
|
||||
ServeDir::new(minimal_path.clone()).append_index_html_on_directories(true),
|
||||
),
|
||||
)
|
||||
.with_state(client)
|
||||
}
|
||||
|
||||
async fn health(
|
||||
State(client): State<Arc<BotServerClient>>,
|
||||
) -> (StatusCode, axum::Json<serde_json::Value>) {
|
||||
match client.health_check().await {
|
||||
/// Health check endpoint - checks BotServer connectivity
|
||||
async fn health(State(state): State<AppState>) -> (StatusCode, axum::Json<serde_json::Value>) {
|
||||
match state.health_check().await {
|
||||
true => (
|
||||
StatusCode::OK,
|
||||
axum::Json(serde_json::json!({
|
||||
|
|
@ -114,25 +71,95 @@ async fn health(
|
|||
}
|
||||
}
|
||||
|
||||
/// API health check endpoint
|
||||
async fn api_health() -> (StatusCode, axum::Json<serde_json::Value>) {
|
||||
(
|
||||
StatusCode::OK,
|
||||
axum::Json(serde_json::json!({
|
||||
"status": "ok",
|
||||
"version": "1.0.0"
|
||||
"version": env!("CARGO_PKG_VERSION")
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
async fn root() -> axum::Json<serde_json::Value> {
|
||||
axum::Json(serde_json::json!({
|
||||
"service": "BotUI",
|
||||
"version": "1.0.0",
|
||||
"description": "General Bots User Interface",
|
||||
"endpoints": {
|
||||
"health": "/health",
|
||||
"api": "/api/health",
|
||||
"ui": "/"
|
||||
}
|
||||
}))
|
||||
/// Configure and return the main router
|
||||
pub fn configure_router() -> Router {
|
||||
let suite_path = PathBuf::from("./ui/suite");
|
||||
let minimal_path = PathBuf::from("./ui/minimal");
|
||||
let state = AppState::new();
|
||||
|
||||
Router::new()
|
||||
// Health check endpoints
|
||||
.route("/health", get(health))
|
||||
.route("/api/health", get(api_health))
|
||||
// UI routes
|
||||
.route("/", get(index))
|
||||
.route("/minimal", get(serve_minimal))
|
||||
.route("/suite", get(serve_suite))
|
||||
// Suite static assets (when accessing /suite/*)
|
||||
.nest_service(
|
||||
"/suite/js",
|
||||
tower_http::services::ServeDir::new(suite_path.join("js")),
|
||||
)
|
||||
.nest_service(
|
||||
"/suite/css",
|
||||
tower_http::services::ServeDir::new(suite_path.join("css")),
|
||||
)
|
||||
.nest_service(
|
||||
"/suite/public",
|
||||
tower_http::services::ServeDir::new(suite_path.join("public")),
|
||||
)
|
||||
.nest_service(
|
||||
"/suite/drive",
|
||||
tower_http::services::ServeDir::new(suite_path.join("drive")),
|
||||
)
|
||||
.nest_service(
|
||||
"/suite/chat",
|
||||
tower_http::services::ServeDir::new(suite_path.join("chat")),
|
||||
)
|
||||
.nest_service(
|
||||
"/suite/mail",
|
||||
tower_http::services::ServeDir::new(suite_path.join("mail")),
|
||||
)
|
||||
.nest_service(
|
||||
"/suite/tasks",
|
||||
tower_http::services::ServeDir::new(suite_path.join("tasks")),
|
||||
)
|
||||
// Legacy paths for backward compatibility (serve suite assets)
|
||||
.nest_service(
|
||||
"/js",
|
||||
tower_http::services::ServeDir::new(suite_path.join("js")),
|
||||
)
|
||||
.nest_service(
|
||||
"/css",
|
||||
tower_http::services::ServeDir::new(suite_path.join("css")),
|
||||
)
|
||||
.nest_service(
|
||||
"/public",
|
||||
tower_http::services::ServeDir::new(suite_path.join("public")),
|
||||
)
|
||||
.nest_service(
|
||||
"/drive",
|
||||
tower_http::services::ServeDir::new(suite_path.join("drive")),
|
||||
)
|
||||
.nest_service(
|
||||
"/chat",
|
||||
tower_http::services::ServeDir::new(suite_path.join("chat")),
|
||||
)
|
||||
.nest_service(
|
||||
"/mail",
|
||||
tower_http::services::ServeDir::new(suite_path.join("mail")),
|
||||
)
|
||||
.nest_service(
|
||||
"/tasks",
|
||||
tower_http::services::ServeDir::new(suite_path.join("tasks")),
|
||||
)
|
||||
// Fallback for other static files
|
||||
.fallback_service(
|
||||
tower_http::services::ServeDir::new(minimal_path.clone()).fallback(
|
||||
tower_http::services::ServeDir::new(minimal_path)
|
||||
.append_index_html_on_directories(true),
|
||||
),
|
||||
)
|
||||
.with_state(state)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
#![cfg(not(feature = "desktop"))]
|
||||
|
||||
use axum::{extract::State, http::StatusCode, Json};
|
||||
use serde_json::json;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::http_client::BotServerClient;
|
||||
|
||||
/// Health check endpoint
|
||||
pub async fn health(
|
||||
State(client): State<Arc<BotServerClient>>,
|
||||
) -> (StatusCode, Json<serde_json::Value>) {
|
||||
match client.health_check().await {
|
||||
true => (
|
||||
StatusCode::OK,
|
||||
Json(json!({
|
||||
"status": "healthy",
|
||||
"service": "botui",
|
||||
"mode": "web"
|
||||
})),
|
||||
),
|
||||
false => (
|
||||
StatusCode::SERVICE_UNAVAILABLE,
|
||||
Json(json!({
|
||||
"status": "unhealthy",
|
||||
"service": "botui",
|
||||
"error": "botserver unreachable"
|
||||
})),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// API health check endpoint
|
||||
pub async fn api_health() -> (StatusCode, Json<serde_json::Value>) {
|
||||
(
|
||||
StatusCode::OK,
|
||||
Json(json!({
|
||||
"status": "ok",
|
||||
"version": "1.0.0"
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
/// Root endpoint
|
||||
pub async fn root() -> Json<serde_json::Value> {
|
||||
Json(json!({
|
||||
"service": "BotUI",
|
||||
"version": "1.0.0",
|
||||
"description": "General Bots User Interface",
|
||||
"endpoints": {
|
||||
"health": "/health",
|
||||
"api": "/api/health",
|
||||
"ui": "/"
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
//! Web module with basic data structures
|
||||
//!
|
||||
//! Contains DTOs and types for the web API layer.
|
||||
|
||||
#![allow(dead_code)] // DTOs prepared for future use
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Request/Response DTOs for web API
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct Message {
|
||||
pub id: String,
|
||||
pub session_id: String,
|
||||
pub sender: String,
|
||||
pub content: String,
|
||||
pub timestamp: String,
|
||||
pub is_user: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct ScanRequest {
|
||||
pub bot_id: Option<String>,
|
||||
pub include_info: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct IssueResponse {
|
||||
pub id: String,
|
||||
pub severity: String,
|
||||
pub issue_type: String,
|
||||
pub title: String,
|
||||
pub description: String,
|
||||
pub file_path: String,
|
||||
pub line_number: Option<usize>,
|
||||
pub code_snippet: Option<String>,
|
||||
pub remediation: String,
|
||||
pub category: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ScanSummary {
|
||||
pub total_issues: usize,
|
||||
pub critical_count: usize,
|
||||
pub high_count: usize,
|
||||
pub total_files_scanned: usize,
|
||||
pub compliance_score: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ScanResponse {
|
||||
pub scan_id: String,
|
||||
pub issues: Vec<IssueResponse>,
|
||||
pub summary: ScanSummary,
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue