2026-01-14 12:36:18 -03:00
|
|
|
#![recursion_limit = "512"]
|
|
|
|
|
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
// Use jemalloc as the global allocator when the feature is enabled
|
|
|
|
|
#[cfg(feature = "jemalloc")]
|
|
|
|
|
use tikv_jemallocator::Jemalloc;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "jemalloc")]
|
|
|
|
|
#[global_allocator]
|
|
|
|
|
static GLOBAL: Jemalloc = Jemalloc;
|
|
|
|
|
|
2026-01-14 12:36:18 -03:00
|
|
|
// Module declarations
|
|
|
|
|
pub mod auto_task;
|
|
|
|
|
pub mod basic;
|
|
|
|
|
pub mod billing;
|
|
|
|
|
pub mod canvas;
|
|
|
|
|
pub mod channels;
|
|
|
|
|
pub mod contacts;
|
|
|
|
|
pub mod core;
|
|
|
|
|
pub mod dashboards;
|
|
|
|
|
pub mod embedded_ui;
|
|
|
|
|
pub mod maintenance;
|
|
|
|
|
pub mod multimodal;
|
|
|
|
|
pub mod player;
|
|
|
|
|
pub mod people;
|
|
|
|
|
pub mod products;
|
|
|
|
|
pub mod search;
|
|
|
|
|
pub mod security;
|
|
|
|
|
pub mod tickets;
|
|
|
|
|
pub mod attendant;
|
|
|
|
|
pub mod analytics;
|
|
|
|
|
pub mod designer;
|
|
|
|
|
pub mod docs;
|
|
|
|
|
pub mod learn;
|
|
|
|
|
pub mod paper;
|
|
|
|
|
pub mod research;
|
|
|
|
|
pub mod sheet;
|
|
|
|
|
pub mod slides;
|
|
|
|
|
pub mod social;
|
|
|
|
|
pub mod sources;
|
|
|
|
|
pub mod video;
|
|
|
|
|
pub mod monitoring;
|
|
|
|
|
pub mod project;
|
|
|
|
|
pub mod workspaces;
|
|
|
|
|
pub mod botmodels;
|
|
|
|
|
pub mod legal;
|
|
|
|
|
pub mod settings;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "attendance")]
|
|
|
|
|
pub mod attendance;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "calendar")]
|
|
|
|
|
pub mod calendar;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "compliance")]
|
|
|
|
|
pub mod compliance;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "console")]
|
|
|
|
|
pub mod console;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "directory")]
|
|
|
|
|
pub mod directory;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "drive")]
|
|
|
|
|
pub mod drive;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "email")]
|
|
|
|
|
pub mod email;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "instagram")]
|
|
|
|
|
pub mod instagram;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "llm")]
|
|
|
|
|
pub mod llm;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "meet")]
|
|
|
|
|
pub mod meet;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "msteams")]
|
|
|
|
|
pub mod msteams;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "nvidia")]
|
|
|
|
|
pub mod nvidia;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "tasks")]
|
|
|
|
|
pub mod tasks;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "vectordb")]
|
|
|
|
|
#[path = "vector-db/mod.rs"]
|
|
|
|
|
pub mod vector_db;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "weba")]
|
|
|
|
|
pub mod weba;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "whatsapp")]
|
|
|
|
|
pub mod whatsapp;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "telegram")]
|
|
|
|
|
pub mod telegram;
|
|
|
|
|
|
|
|
|
|
pub use core::shared;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub enum BootstrapProgress {
|
|
|
|
|
StartingBootstrap,
|
|
|
|
|
InstallingComponent(String),
|
|
|
|
|
StartingComponent(String),
|
|
|
|
|
UploadingTemplates,
|
|
|
|
|
ConnectingDatabase,
|
|
|
|
|
StartingLLM,
|
|
|
|
|
BootstrapComplete,
|
|
|
|
|
BootstrapError(String),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "drive")]
|
|
|
|
|
pub use drive::drive_monitor::DriveMonitor;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "llm")]
|
|
|
|
|
pub use llm::cache::{CacheConfig, CachedLLMProvider, CachedResponse, LocalEmbeddingService};
|
|
|
|
|
#[cfg(feature = "llm")]
|
|
|
|
|
pub use llm::DynamicLLMProvider;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "tasks")]
|
|
|
|
|
pub use tasks::TaskEngine;
|
|
|
|
|
|
2025-12-08 14:08:49 -03:00
|
|
|
use axum::extract::{Extension, State};
|
|
|
|
|
use axum::http::StatusCode;
|
feat(security): Complete security infrastructure implementation
SECURITY MODULES ADDED:
- security/auth.rs: Full RBAC with roles (Anonymous, User, Moderator, Admin, SuperAdmin, Service, Bot, BotOwner, BotOperator, BotViewer) and permissions
- security/cors.rs: Hardened CORS (no wildcard in production, env-based config)
- security/panic_handler.rs: Panic catching middleware with safe 500 responses
- security/path_guard.rs: Path traversal protection, null byte prevention
- security/request_id.rs: UUID request tracking with correlation IDs
- security/error_sanitizer.rs: Sensitive data redaction from responses
- security/zitadel_auth.rs: Zitadel token introspection and role mapping
- security/sql_guard.rs: SQL injection prevention with table whitelist
- security/command_guard.rs: Command injection prevention
- security/secrets.rs: Zeroizing secret management
- security/validation.rs: Input validation utilities
- security/rate_limiter.rs: Rate limiting with governor crate
- security/headers.rs: Security headers (CSP, HSTS, X-Frame-Options)
MAIN.RS UPDATES:
- Replaced tower_http::cors::Any with hardened create_cors_layer()
- Added panic handler middleware
- Added request ID tracking middleware
- Set global panic hook
SECURITY STATUS:
- 0 unwrap() in production code
- 0 panic! in production code
- 0 unsafe blocks
- cargo audit: PASS (no vulnerabilities)
- Estimated completion: ~98%
Remaining: Wire auth middleware to handlers, audit logs for sensitive data
2025-12-28 19:29:18 -03:00
|
|
|
use axum::middleware;
|
2025-12-08 14:08:49 -03:00
|
|
|
use axum::Json;
|
2025-11-20 13:28:35 -03:00
|
|
|
use axum::{
|
|
|
|
|
routing::{get, post},
|
|
|
|
|
Router,
|
|
|
|
|
};
|
2025-12-02 21:09:43 -03:00
|
|
|
use dotenvy::dotenv;
|
2025-11-28 13:50:28 -03:00
|
|
|
use log::{error, info, trace, warn};
|
2025-10-12 20:12:49 -03:00
|
|
|
use std::collections::HashMap;
|
2025-11-20 13:28:35 -03:00
|
|
|
use std::net::SocketAddr;
|
2025-11-11 09:42:52 -03:00
|
|
|
use std::sync::Arc;
|
feat(security): Complete security infrastructure implementation
SECURITY MODULES ADDED:
- security/auth.rs: Full RBAC with roles (Anonymous, User, Moderator, Admin, SuperAdmin, Service, Bot, BotOwner, BotOperator, BotViewer) and permissions
- security/cors.rs: Hardened CORS (no wildcard in production, env-based config)
- security/panic_handler.rs: Panic catching middleware with safe 500 responses
- security/path_guard.rs: Path traversal protection, null byte prevention
- security/request_id.rs: UUID request tracking with correlation IDs
- security/error_sanitizer.rs: Sensitive data redaction from responses
- security/zitadel_auth.rs: Zitadel token introspection and role mapping
- security/sql_guard.rs: SQL injection prevention with table whitelist
- security/command_guard.rs: Command injection prevention
- security/secrets.rs: Zeroizing secret management
- security/validation.rs: Input validation utilities
- security/rate_limiter.rs: Rate limiting with governor crate
- security/headers.rs: Security headers (CSP, HSTS, X-Frame-Options)
MAIN.RS UPDATES:
- Replaced tower_http::cors::Any with hardened create_cors_layer()
- Added panic handler middleware
- Added request ID tracking middleware
- Set global panic hook
SECURITY STATUS:
- 0 unwrap() in production code
- 0 panic! in production code
- 0 unsafe blocks
- cargo audit: PASS (no vulnerabilities)
- Estimated completion: ~98%
Remaining: Wire auth middleware to handlers, audit logs for sensitive data
2025-12-28 19:29:18 -03:00
|
|
|
|
2025-12-17 17:41:37 -03:00
|
|
|
use tower_http::services::ServeDir;
|
2025-11-20 13:28:35 -03:00
|
|
|
use tower_http::trace::TraceLayer;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2026-01-14 12:36:18 -03:00
|
|
|
use crate::embedded_ui;
|
2026-01-09 19:19:41 -03:00
|
|
|
|
2026-01-02 18:26:34 -03:00
|
|
|
async fn ensure_vendor_files_in_minio(drive: &aws_sdk_s3::Client) {
|
|
|
|
|
use aws_sdk_s3::primitives::ByteStream;
|
|
|
|
|
|
2026-01-06 22:56:35 -03:00
|
|
|
let htmx_paths = [
|
|
|
|
|
"./botui/ui/suite/js/vendor/htmx.min.js",
|
|
|
|
|
"../botui/ui/suite/js/vendor/htmx.min.js",
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
let htmx_content = htmx_paths
|
|
|
|
|
.iter()
|
|
|
|
|
.find_map(|path| std::fs::read(path).ok());
|
|
|
|
|
|
|
|
|
|
let Some(content) = htmx_content else {
|
|
|
|
|
warn!("Could not find htmx.min.js in botui, skipping MinIO upload");
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
|
2026-01-02 18:26:34 -03:00
|
|
|
let bucket = "default.gbai";
|
|
|
|
|
let key = "default.gblib/vendor/htmx.min.js";
|
|
|
|
|
|
|
|
|
|
match drive
|
|
|
|
|
.put_object()
|
|
|
|
|
.bucket(bucket)
|
|
|
|
|
.key(key)
|
2026-01-06 22:56:35 -03:00
|
|
|
.body(ByteStream::from(content))
|
2026-01-02 18:26:34 -03:00
|
|
|
.content_type("application/javascript")
|
|
|
|
|
.send()
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(_) => info!("Uploaded vendor file to MinIO: s3://{}/{}", bucket, key),
|
|
|
|
|
Err(e) => warn!("Failed to upload vendor file to MinIO: {}", e),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-14 12:36:18 -03:00
|
|
|
use crate::security::{
|
2026-01-10 09:41:12 -03:00
|
|
|
create_cors_layer, create_rate_limit_layer, create_security_headers_layer,
|
feat(security): Complete security wiring and log audit
SECURITY WIRING:
- Auth middleware wired to main router with AnonymousPath config
- CORS allowed origins loaded from bot_configuration database (config.csv)
- Zitadel auth config loads from Vault via SecretsManager
- No more env vars for sensitive config (only VAULT_* allowed)
LOG AUDIT:
- Added is_sensitive_config_key() check in ask_later.rs
- Sensitive config values (password, secret, token, key, etc) now logged as [REDACTED]
- Removed potential credential exposure in pending_info logs
CONFIG LOADING ORDER:
1. VAULT_ADDR and VAULT_TOKEN from .env
2. All secrets from Vault (gbo/directory for Zitadel)
3. Bot config from config.csv (cors-allowed-origins, etc)
Auth Config Paths:
- Anonymous: /health, /healthz, /api/health, /ws, /auth
- Public: /static, /favicon.ico
2025-12-28 19:41:33 -03:00
|
|
|
request_id_middleware, security_headers_middleware, set_cors_allowed_origins,
|
|
|
|
|
set_global_panic_hook, AuthConfig, HttpRateLimitConfig, PanicHandlerConfig,
|
2026-01-10 09:41:12 -03:00
|
|
|
SecurityHeadersConfig, AuthProviderBuilder, ApiKeyAuthProvider, JwtConfig, JwtKey,
|
|
|
|
|
JwtManager, RbacManager, RbacConfig, AuthMiddlewareState,
|
|
|
|
|
build_default_route_permissions,
|
feat(security): Complete security infrastructure implementation
SECURITY MODULES ADDED:
- security/auth.rs: Full RBAC with roles (Anonymous, User, Moderator, Admin, SuperAdmin, Service, Bot, BotOwner, BotOperator, BotViewer) and permissions
- security/cors.rs: Hardened CORS (no wildcard in production, env-based config)
- security/panic_handler.rs: Panic catching middleware with safe 500 responses
- security/path_guard.rs: Path traversal protection, null byte prevention
- security/request_id.rs: UUID request tracking with correlation IDs
- security/error_sanitizer.rs: Sensitive data redaction from responses
- security/zitadel_auth.rs: Zitadel token introspection and role mapping
- security/sql_guard.rs: SQL injection prevention with table whitelist
- security/command_guard.rs: Command injection prevention
- security/secrets.rs: Zeroizing secret management
- security/validation.rs: Input validation utilities
- security/rate_limiter.rs: Rate limiting with governor crate
- security/headers.rs: Security headers (CSP, HSTS, X-Frame-Options)
MAIN.RS UPDATES:
- Replaced tower_http::cors::Any with hardened create_cors_layer()
- Added panic handler middleware
- Added request ID tracking middleware
- Set global panic hook
SECURITY STATUS:
- 0 unwrap() in production code
- 0 panic! in production code
- 0 unsafe blocks
- cargo audit: PASS (no vulnerabilities)
- Estimated completion: ~98%
Remaining: Wire auth middleware to handlers, audit logs for sensitive data
2025-12-28 19:29:18 -03:00
|
|
|
};
|
|
|
|
|
use botlib::SystemLimits;
|
|
|
|
|
|
2026-01-14 12:36:18 -03:00
|
|
|
use crate::core::shared::memory_monitor::{
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
start_memory_monitor, log_process_memory, MemoryStats,
|
|
|
|
|
register_thread, record_thread_activity
|
|
|
|
|
};
|
2025-11-27 23:10:43 -03:00
|
|
|
|
2026-01-14 12:36:18 -03:00
|
|
|
use crate::core::automation;
|
|
|
|
|
use crate::core::bootstrap;
|
|
|
|
|
use crate::core::bot;
|
|
|
|
|
use crate::core::package_manager;
|
|
|
|
|
use crate::core::session;
|
2025-11-22 22:54:45 -03:00
|
|
|
|
2025-12-17 17:41:37 -03:00
|
|
|
use automation::AutomationService;
|
|
|
|
|
use bootstrap::BootstrapManager;
|
2026-01-14 12:36:18 -03:00
|
|
|
use crate::core::bot::channels::{VoiceAdapter, WebChannelAdapter};
|
|
|
|
|
use crate::core::bot::websocket_handler;
|
|
|
|
|
use crate::core::bot::BotOrchestrator;
|
|
|
|
|
use crate::core::bot_database::BotDatabaseManager;
|
|
|
|
|
use crate::core::config::AppConfig;
|
2025-11-27 15:19:17 -03:00
|
|
|
|
2025-11-22 22:54:45 -03:00
|
|
|
#[cfg(feature = "directory")]
|
2026-01-14 12:36:18 -03:00
|
|
|
use crate::directory::auth_handler;
|
2025-12-29 18:21:03 -03:00
|
|
|
|
2025-12-17 17:41:37 -03:00
|
|
|
use package_manager::InstallMode;
|
|
|
|
|
use session::{create_session, get_session_history, get_sessions, start_session};
|
2026-01-14 12:36:18 -03:00
|
|
|
use crate::shared::state::AppState;
|
|
|
|
|
use crate::shared::utils::create_conn;
|
|
|
|
|
use crate::shared::utils::create_s3_operator;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2026-01-14 12:36:18 -03:00
|
|
|
use crate::BootstrapProgress;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-08 14:08:49 -03:00
|
|
|
async fn health_check(State(state): State<Arc<AppState>>) -> (StatusCode, Json<serde_json::Value>) {
|
|
|
|
|
let db_ok = state.conn.get().is_ok();
|
|
|
|
|
|
|
|
|
|
let status = if db_ok { "healthy" } else { "degraded" };
|
|
|
|
|
let code = if db_ok {
|
|
|
|
|
StatusCode::OK
|
|
|
|
|
} else {
|
|
|
|
|
StatusCode::SERVICE_UNAVAILABLE
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
(
|
|
|
|
|
code,
|
|
|
|
|
Json(serde_json::json!({
|
|
|
|
|
"status": status,
|
|
|
|
|
"service": "botserver",
|
|
|
|
|
"version": env!("CARGO_PKG_VERSION"),
|
|
|
|
|
"database": db_ok
|
|
|
|
|
})),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn health_check_simple() -> (StatusCode, Json<serde_json::Value>) {
|
|
|
|
|
(
|
|
|
|
|
StatusCode::OK,
|
|
|
|
|
Json(serde_json::json!({
|
|
|
|
|
"status": "ok",
|
|
|
|
|
"service": "botserver",
|
|
|
|
|
"version": env!("CARGO_PKG_VERSION")
|
|
|
|
|
})),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-10 18:31:58 -03:00
|
|
|
fn print_shutdown_message() {
|
|
|
|
|
println!();
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
println!("Thank you for using General Bots!");
|
2025-12-10 18:31:58 -03:00
|
|
|
println!();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn shutdown_signal() {
|
|
|
|
|
let ctrl_c = async {
|
2025-12-28 21:26:08 -03:00
|
|
|
if let Err(e) = tokio::signal::ctrl_c().await {
|
|
|
|
|
error!("Failed to install Ctrl+C handler: {}", e);
|
|
|
|
|
}
|
2025-12-10 18:31:58 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
|
let terminate = async {
|
2025-12-28 21:26:08 -03:00
|
|
|
match tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) {
|
|
|
|
|
Ok(mut signal) => {
|
|
|
|
|
signal.recv().await;
|
|
|
|
|
}
|
|
|
|
|
Err(e) => {
|
|
|
|
|
error!("Failed to install SIGTERM handler: {}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-10 18:31:58 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
|
|
|
|
let terminate = std::future::pending::<()>();
|
|
|
|
|
|
|
|
|
|
tokio::select! {
|
|
|
|
|
_ = ctrl_c => {
|
|
|
|
|
info!("Received Ctrl+C, initiating graceful shutdown...");
|
|
|
|
|
}
|
|
|
|
|
_ = terminate => {
|
|
|
|
|
info!("Received SIGTERM, initiating graceful shutdown...");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print_shutdown_message();
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-20 13:28:35 -03:00
|
|
|
async fn run_axum_server(
|
2025-11-19 14:00:57 -03:00
|
|
|
app_state: Arc<AppState>,
|
|
|
|
|
port: u16,
|
2025-11-20 13:28:35 -03:00
|
|
|
_worker_count: usize,
|
2025-11-19 14:00:57 -03:00
|
|
|
) -> std::io::Result<()> {
|
feat(security): Complete security wiring and log audit
SECURITY WIRING:
- Auth middleware wired to main router with AnonymousPath config
- CORS allowed origins loaded from bot_configuration database (config.csv)
- Zitadel auth config loads from Vault via SecretsManager
- No more env vars for sensitive config (only VAULT_* allowed)
LOG AUDIT:
- Added is_sensitive_config_key() check in ask_later.rs
- Sensitive config values (password, secret, token, key, etc) now logged as [REDACTED]
- Removed potential credential exposure in pending_info logs
CONFIG LOADING ORDER:
1. VAULT_ADDR and VAULT_TOKEN from .env
2. All secrets from Vault (gbo/directory for Zitadel)
3. Bot config from config.csv (cors-allowed-origins, etc)
Auth Config Paths:
- Anonymous: /health, /healthz, /api/health, /ws, /auth
- Public: /static, /favicon.ico
2025-12-28 19:41:33 -03:00
|
|
|
// Load CORS allowed origins from bot config database if available
|
|
|
|
|
// Config key: cors-allowed-origins in config.csv
|
|
|
|
|
if let Ok(mut conn) = app_state.conn.get() {
|
|
|
|
|
use crate::shared::models::schema::bot_configuration::dsl::*;
|
|
|
|
|
use diesel::prelude::*;
|
|
|
|
|
|
|
|
|
|
if let Ok(origins_str) = bot_configuration
|
|
|
|
|
.filter(config_key.eq("cors-allowed-origins"))
|
|
|
|
|
.select(config_value)
|
|
|
|
|
.first::<String>(&mut conn)
|
|
|
|
|
{
|
|
|
|
|
let origins: Vec<String> = origins_str
|
|
|
|
|
.split(',')
|
|
|
|
|
.map(|s| s.trim().to_string())
|
|
|
|
|
.filter(|s| !s.is_empty())
|
|
|
|
|
.collect();
|
|
|
|
|
if !origins.is_empty() {
|
|
|
|
|
info!("Loaded {} CORS allowed origins from config", origins.len());
|
|
|
|
|
set_cors_allowed_origins(origins);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
feat(security): Complete security infrastructure implementation
SECURITY MODULES ADDED:
- security/auth.rs: Full RBAC with roles (Anonymous, User, Moderator, Admin, SuperAdmin, Service, Bot, BotOwner, BotOperator, BotViewer) and permissions
- security/cors.rs: Hardened CORS (no wildcard in production, env-based config)
- security/panic_handler.rs: Panic catching middleware with safe 500 responses
- security/path_guard.rs: Path traversal protection, null byte prevention
- security/request_id.rs: UUID request tracking with correlation IDs
- security/error_sanitizer.rs: Sensitive data redaction from responses
- security/zitadel_auth.rs: Zitadel token introspection and role mapping
- security/sql_guard.rs: SQL injection prevention with table whitelist
- security/command_guard.rs: Command injection prevention
- security/secrets.rs: Zeroizing secret management
- security/validation.rs: Input validation utilities
- security/rate_limiter.rs: Rate limiting with governor crate
- security/headers.rs: Security headers (CSP, HSTS, X-Frame-Options)
MAIN.RS UPDATES:
- Replaced tower_http::cors::Any with hardened create_cors_layer()
- Added panic handler middleware
- Added request ID tracking middleware
- Set global panic hook
SECURITY STATUS:
- 0 unwrap() in production code
- 0 panic! in production code
- 0 unsafe blocks
- cargo audit: PASS (no vulnerabilities)
- Estimated completion: ~98%
Remaining: Wire auth middleware to handlers, audit logs for sensitive data
2025-12-28 19:29:18 -03:00
|
|
|
let cors = create_cors_layer();
|
2025-11-20 13:28:35 -03:00
|
|
|
|
2026-01-10 09:41:12 -03:00
|
|
|
let auth_config = Arc::new(AuthConfig::from_env()
|
feat(security): Complete security wiring and log audit
SECURITY WIRING:
- Auth middleware wired to main router with AnonymousPath config
- CORS allowed origins loaded from bot_configuration database (config.csv)
- Zitadel auth config loads from Vault via SecretsManager
- No more env vars for sensitive config (only VAULT_* allowed)
LOG AUDIT:
- Added is_sensitive_config_key() check in ask_later.rs
- Sensitive config values (password, secret, token, key, etc) now logged as [REDACTED]
- Removed potential credential exposure in pending_info logs
CONFIG LOADING ORDER:
1. VAULT_ADDR and VAULT_TOKEN from .env
2. All secrets from Vault (gbo/directory for Zitadel)
3. Bot config from config.csv (cors-allowed-origins, etc)
Auth Config Paths:
- Anonymous: /health, /healthz, /api/health, /ws, /auth
- Public: /static, /favicon.ico
2025-12-28 19:41:33 -03:00
|
|
|
.add_anonymous_path("/health")
|
|
|
|
|
.add_anonymous_path("/healthz")
|
2026-01-10 09:41:12 -03:00
|
|
|
.add_anonymous_path("/api/health")
|
|
|
|
|
.add_anonymous_path("/api/product")
|
2026-01-10 10:27:01 -03:00
|
|
|
.add_anonymous_path("/api/i18n")
|
2026-01-10 17:31:50 -03:00
|
|
|
.add_anonymous_path("/api/auth/login")
|
|
|
|
|
.add_anonymous_path("/api/auth/refresh")
|
|
|
|
|
.add_anonymous_path("/api/auth/bootstrap")
|
feat(security): Complete security wiring and log audit
SECURITY WIRING:
- Auth middleware wired to main router with AnonymousPath config
- CORS allowed origins loaded from bot_configuration database (config.csv)
- Zitadel auth config loads from Vault via SecretsManager
- No more env vars for sensitive config (only VAULT_* allowed)
LOG AUDIT:
- Added is_sensitive_config_key() check in ask_later.rs
- Sensitive config values (password, secret, token, key, etc) now logged as [REDACTED]
- Removed potential credential exposure in pending_info logs
CONFIG LOADING ORDER:
1. VAULT_ADDR and VAULT_TOKEN from .env
2. All secrets from Vault (gbo/directory for Zitadel)
3. Bot config from config.csv (cors-allowed-origins, etc)
Auth Config Paths:
- Anonymous: /health, /healthz, /api/health, /ws, /auth
- Public: /static, /favicon.ico
2025-12-28 19:41:33 -03:00
|
|
|
.add_anonymous_path("/ws")
|
|
|
|
|
.add_anonymous_path("/auth")
|
|
|
|
|
.add_public_path("/static")
|
2025-12-31 13:11:16 -03:00
|
|
|
.add_public_path("/favicon.ico")
|
2026-01-10 09:41:12 -03:00
|
|
|
.add_public_path("/suite")
|
|
|
|
|
.add_public_path("/themes"));
|
|
|
|
|
|
|
|
|
|
let jwt_secret = std::env::var("JWT_SECRET")
|
|
|
|
|
.unwrap_or_else(|_| {
|
|
|
|
|
warn!("JWT_SECRET not set, using default development secret - DO NOT USE IN PRODUCTION");
|
|
|
|
|
"dev-secret-key-change-in-production-minimum-32-chars".to_string()
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let jwt_config = JwtConfig::default();
|
|
|
|
|
let jwt_key = JwtKey::from_secret(&jwt_secret);
|
|
|
|
|
let jwt_manager = match JwtManager::new(jwt_config, jwt_key) {
|
|
|
|
|
Ok(manager) => {
|
|
|
|
|
info!("JWT Manager initialized successfully");
|
|
|
|
|
Some(Arc::new(manager))
|
|
|
|
|
}
|
|
|
|
|
Err(e) => {
|
|
|
|
|
error!("Failed to initialize JWT Manager: {e}");
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let rbac_config = RbacConfig::default();
|
|
|
|
|
let rbac_manager = Arc::new(RbacManager::new(rbac_config));
|
|
|
|
|
|
|
|
|
|
let default_permissions = build_default_route_permissions();
|
|
|
|
|
rbac_manager.register_routes(default_permissions).await;
|
|
|
|
|
info!("RBAC Manager initialized with {} default route permissions",
|
|
|
|
|
rbac_manager.config().cache_ttl_seconds);
|
|
|
|
|
|
|
|
|
|
let auth_provider_registry = {
|
|
|
|
|
let mut builder = AuthProviderBuilder::new()
|
|
|
|
|
.with_api_key_provider(Arc::new(ApiKeyAuthProvider::new()))
|
|
|
|
|
.with_auth_config(Arc::clone(&auth_config));
|
|
|
|
|
|
|
|
|
|
if let Some(ref manager) = jwt_manager {
|
|
|
|
|
builder = builder.with_jwt_manager(Arc::clone(manager));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let zitadel_configured = std::env::var("ZITADEL_ISSUER_URL").is_ok()
|
|
|
|
|
&& std::env::var("ZITADEL_CLIENT_ID").is_ok();
|
|
|
|
|
|
|
|
|
|
if zitadel_configured {
|
|
|
|
|
info!("Zitadel environment variables detected - external IdP authentication available");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Arc::new(builder.build().await)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
info!("Auth provider registry initialized with {} providers",
|
|
|
|
|
auth_provider_registry.provider_count().await);
|
|
|
|
|
|
|
|
|
|
let auth_middleware_state = AuthMiddlewareState::new(
|
|
|
|
|
Arc::clone(&auth_config),
|
|
|
|
|
Arc::clone(&auth_provider_registry),
|
|
|
|
|
);
|
feat(security): Complete security wiring and log audit
SECURITY WIRING:
- Auth middleware wired to main router with AnonymousPath config
- CORS allowed origins loaded from bot_configuration database (config.csv)
- Zitadel auth config loads from Vault via SecretsManager
- No more env vars for sensitive config (only VAULT_* allowed)
LOG AUDIT:
- Added is_sensitive_config_key() check in ask_later.rs
- Sensitive config values (password, secret, token, key, etc) now logged as [REDACTED]
- Removed potential credential exposure in pending_info logs
CONFIG LOADING ORDER:
1. VAULT_ADDR and VAULT_TOKEN from .env
2. All secrets from Vault (gbo/directory for Zitadel)
3. Bot config from config.csv (cors-allowed-origins, etc)
Auth Config Paths:
- Anonymous: /health, /healthz, /api/health, /ws, /auth
- Public: /static, /favicon.ico
2025-12-28 19:41:33 -03:00
|
|
|
|
2025-11-29 16:29:28 -03:00
|
|
|
use crate::core::urls::ApiUrls;
|
2026-01-06 22:56:35 -03:00
|
|
|
use crate::core::product::{PRODUCT_CONFIG, get_product_config_json};
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
let config = PRODUCT_CONFIG.read().expect("Failed to read product config");
|
|
|
|
|
info!("Product: {} | Theme: {} | Apps: {:?}",
|
|
|
|
|
config.name, config.theme, config.get_enabled_apps());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn get_product_config() -> Json<serde_json::Value> {
|
|
|
|
|
Json(get_product_config_json())
|
|
|
|
|
}
|
2025-11-29 16:29:28 -03:00
|
|
|
|
2025-11-27 09:38:50 -03:00
|
|
|
let mut api_router = Router::new()
|
2025-12-08 14:08:49 -03:00
|
|
|
.route("/health", get(health_check_simple))
|
|
|
|
|
.route(ApiUrls::HEALTH, get(health_check))
|
2026-01-06 22:56:35 -03:00
|
|
|
.route("/api/product", get(get_product_config))
|
2025-11-29 16:29:28 -03:00
|
|
|
.route(ApiUrls::SESSIONS, post(create_session))
|
|
|
|
|
.route(ApiUrls::SESSIONS, get(get_sessions))
|
2026-01-06 22:56:35 -03:00
|
|
|
.route(ApiUrls::SESSION_HISTORY, get(get_session_history))
|
|
|
|
|
.route(ApiUrls::SESSION_START, post(start_session))
|
2025-11-29 16:29:28 -03:00
|
|
|
.route(ApiUrls::WS, get(websocket_handler))
|
2025-11-27 23:10:43 -03:00
|
|
|
.merge(botserver::drive::configure());
|
2025-11-22 22:54:45 -03:00
|
|
|
|
|
|
|
|
#[cfg(feature = "directory")]
|
|
|
|
|
{
|
2025-11-29 16:29:28 -03:00
|
|
|
api_router = api_router
|
|
|
|
|
.route(ApiUrls::AUTH, get(auth_handler))
|
2025-12-17 17:41:37 -03:00
|
|
|
.merge(crate::core::directory::api::configure_user_routes())
|
2026-01-06 22:56:35 -03:00
|
|
|
.merge(crate::directory::router::configure())
|
|
|
|
|
.merge(crate::directory::auth_routes::configure());
|
2025-11-22 22:54:45 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "meet")]
|
|
|
|
|
{
|
2025-12-29 18:21:03 -03:00
|
|
|
api_router = api_router.merge(crate::meet::configure());
|
2025-11-22 22:54:45 -03:00
|
|
|
}
|
|
|
|
|
|
2025-11-26 22:54:22 -03:00
|
|
|
#[cfg(feature = "email")]
|
2025-11-22 22:54:45 -03:00
|
|
|
{
|
2025-11-26 22:54:22 -03:00
|
|
|
api_router = api_router.merge(crate::email::configure());
|
2025-11-22 22:54:45 -03:00
|
|
|
}
|
|
|
|
|
|
2025-11-26 22:54:22 -03:00
|
|
|
#[cfg(feature = "calendar")]
|
|
|
|
|
{
|
|
|
|
|
let calendar_engine =
|
2026-01-13 22:21:25 -03:00
|
|
|
Arc::new(botserver::basic::keywords::book::CalendarEngine::new(app_state.conn.clone()));
|
2025-11-26 22:54:22 -03:00
|
|
|
|
|
|
|
|
api_router = api_router.merge(crate::calendar::caldav::create_caldav_router(
|
|
|
|
|
calendar_engine,
|
|
|
|
|
));
|
|
|
|
|
}
|
2025-11-22 12:26:16 -03:00
|
|
|
|
2025-11-27 08:34:24 -03:00
|
|
|
api_router = api_router.merge(botserver::tasks::configure_task_routes());
|
2025-11-20 13:28:35 -03:00
|
|
|
|
2025-11-27 09:38:50 -03:00
|
|
|
#[cfg(feature = "calendar")]
|
|
|
|
|
{
|
|
|
|
|
api_router = api_router.merge(crate::calendar::configure_calendar_routes());
|
Implement database persistence for dashboards, legal, and compliance modules
- Add PostgreSQL persistence for dashboards module (was returning empty vec![])
- Tables: dashboards, dashboard_widgets, dashboard_data_sources, dashboard_filters,
dashboard_widget_data_sources, conversational_queries
- Full CRUD operations with spawn_blocking pattern
- Add PostgreSQL persistence for legal module (was using in-memory HashMap)
- Tables: legal_documents, legal_document_versions, cookie_consents, consent_history,
legal_acceptances, data_deletion_requests, data_export_requests
- GDPR-compliant consent tracking and document management
- Add PostgreSQL persistence for compliance module (was returning empty results)
- Tables: compliance_checks, compliance_issues, compliance_audit_log, compliance_evidence,
compliance_risk_assessments, compliance_risks, compliance_training_records,
compliance_access_reviews
- Support for GDPR, SOC2, ISO27001, HIPAA, PCI-DSS frameworks
- Add migration files for all new tables
- Update schema.rs with new table definitions and joinables
- Register new routes in main.rs
- Add recursion_limit = 512 for macro expansion
2026-01-13 00:07:22 -03:00
|
|
|
api_router = api_router.merge(crate::calendar::ui::configure_calendar_ui_routes());
|
2025-11-27 09:38:50 -03:00
|
|
|
}
|
|
|
|
|
|
2025-12-02 21:09:43 -03:00
|
|
|
api_router = api_router.merge(botserver::analytics::configure_analytics_routes());
|
2026-01-06 22:56:35 -03:00
|
|
|
api_router = api_router.merge(crate::core::i18n::configure_i18n_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::docs::configure_docs_routes());
|
2025-12-02 21:09:43 -03:00
|
|
|
api_router = api_router.merge(botserver::paper::configure_paper_routes());
|
2026-01-06 22:56:35 -03:00
|
|
|
api_router = api_router.merge(botserver::sheet::configure_sheet_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::slides::configure_slides_routes());
|
Add video module, RBAC, security features, billing, contacts, dashboards, learn, social, and multiple new modules
Major additions:
- Video editing engine with AI features (transcription, captions, TTS, scene detection)
- RBAC middleware and organization management
- Security enhancements (MFA, passkey, DLP, encryption, audit)
- Billing and subscription management
- Contacts management
- Dashboards module
- Learn/LMS module
- Social features
- Compliance (SOC2, SOP middleware, vulnerability scanner)
- New migrations for RBAC, learn, and video tables
2026-01-08 13:16:17 -03:00
|
|
|
api_router = api_router.merge(botserver::video::configure_video_routes());
|
2026-01-13 14:48:49 -03:00
|
|
|
api_router = api_router.merge(botserver::video::ui::configure_video_ui_routes());
|
2025-12-02 21:09:43 -03:00
|
|
|
api_router = api_router.merge(botserver::research::configure_research_routes());
|
2026-01-13 14:48:49 -03:00
|
|
|
api_router = api_router.merge(botserver::research::ui::configure_research_ui_routes());
|
2025-12-02 21:09:43 -03:00
|
|
|
api_router = api_router.merge(botserver::sources::configure_sources_routes());
|
2026-01-13 14:48:49 -03:00
|
|
|
api_router = api_router.merge(botserver::sources::ui::configure_sources_ui_routes());
|
2025-12-02 21:09:43 -03:00
|
|
|
api_router = api_router.merge(botserver::designer::configure_designer_routes());
|
2026-01-13 14:48:49 -03:00
|
|
|
api_router = api_router.merge(botserver::designer::ui::configure_designer_ui_routes());
|
Add video module, RBAC, security features, billing, contacts, dashboards, learn, social, and multiple new modules
Major additions:
- Video editing engine with AI features (transcription, captions, TTS, scene detection)
- RBAC middleware and organization management
- Security enhancements (MFA, passkey, DLP, encryption, audit)
- Billing and subscription management
- Contacts management
- Dashboards module
- Learn/LMS module
- Social features
- Compliance (SOC2, SOP middleware, vulnerability scanner)
- New migrations for RBAC, learn, and video tables
2026-01-08 13:16:17 -03:00
|
|
|
api_router = api_router.merge(botserver::dashboards::configure_dashboards_routes());
|
2026-01-13 14:48:49 -03:00
|
|
|
api_router = api_router.merge(botserver::dashboards::ui::configure_dashboards_ui_routes());
|
Implement database persistence for dashboards, legal, and compliance modules
- Add PostgreSQL persistence for dashboards module (was returning empty vec![])
- Tables: dashboards, dashboard_widgets, dashboard_data_sources, dashboard_filters,
dashboard_widget_data_sources, conversational_queries
- Full CRUD operations with spawn_blocking pattern
- Add PostgreSQL persistence for legal module (was using in-memory HashMap)
- Tables: legal_documents, legal_document_versions, cookie_consents, consent_history,
legal_acceptances, data_deletion_requests, data_export_requests
- GDPR-compliant consent tracking and document management
- Add PostgreSQL persistence for compliance module (was returning empty results)
- Tables: compliance_checks, compliance_issues, compliance_audit_log, compliance_evidence,
compliance_risk_assessments, compliance_risks, compliance_training_records,
compliance_access_reviews
- Support for GDPR, SOC2, ISO27001, HIPAA, PCI-DSS frameworks
- Add migration files for all new tables
- Update schema.rs with new table definitions and joinables
- Register new routes in main.rs
- Add recursion_limit = 512 for macro expansion
2026-01-13 00:07:22 -03:00
|
|
|
api_router = api_router.merge(botserver::legal::configure_legal_routes());
|
2026-01-13 14:48:49 -03:00
|
|
|
api_router = api_router.merge(botserver::legal::ui::configure_legal_ui_routes());
|
2026-01-13 22:21:25 -03:00
|
|
|
#[cfg(feature = "compliance")]
|
|
|
|
|
{
|
|
|
|
|
api_router = api_router.merge(botserver::compliance::configure_compliance_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::compliance::ui::configure_compliance_ui_routes());
|
|
|
|
|
}
|
2026-01-04 08:48:27 -03:00
|
|
|
api_router = api_router.merge(botserver::monitoring::configure());
|
MS Office 100% Compatibility - Phase 1 Implementation
- Add rust_xlsxwriter for Excel export with formatting support
- Add docx-rs for Word document import/export with HTML conversion
- Add PPTX export support with slides, shapes, and text elements
- Refactor sheet module into 7 files (types, formulas, handlers, etc)
- Refactor docs module into 6 files (types, handlers, storage, etc)
- Refactor slides module into 6 files (types, handlers, storage, etc)
- Fix collaboration modules (borrow issues, rand compatibility)
- Add ooxmlsdk dependency for future Office 2021 features
- Fix type mismatches in slides storage
- Update security protection API router type
Features:
- Excel: Read xlsx/xlsm/xls, write xlsx with styles
- Word: Read/write docx with formatting preservation
- PowerPoint: Write pptx with slides, shapes, text
- Real-time collaboration via WebSocket (already working)
- Theme-aware UI with --sentient-* CSS variables
2026-01-11 09:56:15 -03:00
|
|
|
api_router = api_router.merge(botserver::security::configure_protection_routes());
|
2026-01-04 08:48:27 -03:00
|
|
|
api_router = api_router.merge(botserver::settings::configure_settings_routes());
|
feat(autotask): Implement AutoTask system with intent classification and app generation
- Add IntentClassifier with 7 intent types (APP_CREATE, TODO, MONITOR, ACTION, SCHEDULE, GOAL, TOOL)
- Add AppGenerator with LLM-powered app structure analysis
- Add DesignerAI for modifying apps through conversation
- Add app_server for serving generated apps with clean URLs
- Add db_api for CRUD operations on bot database tables
- Add ask_later keyword for pending info collection
- Add migration 6.1.1 with tables: pending_info, auto_tasks, execution_plans, task_approvals, task_decisions, safety_audit_log, generated_apps, intent_classifications, designer_changes
- Write apps to S3 drive and sync to SITE_ROOT for serving
- Clean URL structure: /apps/{app_name}/
- Integrate with DriveMonitor for file sync
Based on Chapter 17 - Autonomous Tasks specification
2025-12-27 21:10:09 -03:00
|
|
|
api_router = api_router.merge(botserver::basic::keywords::configure_db_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::basic::keywords::configure_app_server_routes());
|
2025-12-27 22:58:43 -03:00
|
|
|
api_router = api_router.merge(botserver::auto_task::configure_autotask_routes());
|
2026-01-06 22:56:35 -03:00
|
|
|
api_router = api_router.merge(crate::core::shared::admin::configure());
|
2026-01-09 19:19:41 -03:00
|
|
|
api_router = api_router.merge(botserver::workspaces::configure_workspaces_routes());
|
Implement database persistence for dashboards, legal, and compliance modules
- Add PostgreSQL persistence for dashboards module (was returning empty vec![])
- Tables: dashboards, dashboard_widgets, dashboard_data_sources, dashboard_filters,
dashboard_widget_data_sources, conversational_queries
- Full CRUD operations with spawn_blocking pattern
- Add PostgreSQL persistence for legal module (was using in-memory HashMap)
- Tables: legal_documents, legal_document_versions, cookie_consents, consent_history,
legal_acceptances, data_deletion_requests, data_export_requests
- GDPR-compliant consent tracking and document management
- Add PostgreSQL persistence for compliance module (was returning empty results)
- Tables: compliance_checks, compliance_issues, compliance_audit_log, compliance_evidence,
compliance_risk_assessments, compliance_risks, compliance_training_records,
compliance_access_reviews
- Support for GDPR, SOC2, ISO27001, HIPAA, PCI-DSS frameworks
- Add migration files for all new tables
- Update schema.rs with new table definitions and joinables
- Register new routes in main.rs
- Add recursion_limit = 512 for macro expansion
2026-01-13 00:07:22 -03:00
|
|
|
api_router = api_router.merge(botserver::workspaces::ui::configure_workspaces_ui_routes());
|
2026-01-09 19:19:41 -03:00
|
|
|
api_router = api_router.merge(botserver::project::configure());
|
|
|
|
|
api_router = api_router.merge(botserver::analytics::goals::configure_goals_routes());
|
Implement database persistence for dashboards, legal, and compliance modules
- Add PostgreSQL persistence for dashboards module (was returning empty vec![])
- Tables: dashboards, dashboard_widgets, dashboard_data_sources, dashboard_filters,
dashboard_widget_data_sources, conversational_queries
- Full CRUD operations with spawn_blocking pattern
- Add PostgreSQL persistence for legal module (was using in-memory HashMap)
- Tables: legal_documents, legal_document_versions, cookie_consents, consent_history,
legal_acceptances, data_deletion_requests, data_export_requests
- GDPR-compliant consent tracking and document management
- Add PostgreSQL persistence for compliance module (was returning empty results)
- Tables: compliance_checks, compliance_issues, compliance_audit_log, compliance_evidence,
compliance_risk_assessments, compliance_risks, compliance_training_records,
compliance_access_reviews
- Support for GDPR, SOC2, ISO27001, HIPAA, PCI-DSS frameworks
- Add migration files for all new tables
- Update schema.rs with new table definitions and joinables
- Register new routes in main.rs
- Add recursion_limit = 512 for macro expansion
2026-01-13 00:07:22 -03:00
|
|
|
api_router = api_router.merge(botserver::analytics::goals_ui::configure_goals_ui_routes());
|
2026-01-09 19:19:41 -03:00
|
|
|
api_router = api_router.merge(botserver::player::configure_player_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::canvas::configure_canvas_routes());
|
Implement database persistence for dashboards, legal, and compliance modules
- Add PostgreSQL persistence for dashboards module (was returning empty vec![])
- Tables: dashboards, dashboard_widgets, dashboard_data_sources, dashboard_filters,
dashboard_widget_data_sources, conversational_queries
- Full CRUD operations with spawn_blocking pattern
- Add PostgreSQL persistence for legal module (was using in-memory HashMap)
- Tables: legal_documents, legal_document_versions, cookie_consents, consent_history,
legal_acceptances, data_deletion_requests, data_export_requests
- GDPR-compliant consent tracking and document management
- Add PostgreSQL persistence for compliance module (was returning empty results)
- Tables: compliance_checks, compliance_issues, compliance_audit_log, compliance_evidence,
compliance_risk_assessments, compliance_risks, compliance_training_records,
compliance_access_reviews
- Support for GDPR, SOC2, ISO27001, HIPAA, PCI-DSS frameworks
- Add migration files for all new tables
- Update schema.rs with new table definitions and joinables
- Register new routes in main.rs
- Add recursion_limit = 512 for macro expansion
2026-01-13 00:07:22 -03:00
|
|
|
api_router = api_router.merge(botserver::canvas::ui::configure_canvas_ui_routes());
|
feat(i18n): add missing translation keys to TRANSLATION_KEYS array
- Add people-* keys (title, subtitle, search, tabs, form fields)
- Add crm-* keys (stages, stats, metrics)
- Add billing-* keys (subtitle, new-payment, revenue metrics)
- Add products-* keys (subtitle, items, stats)
2026-01-12 14:13:35 -03:00
|
|
|
api_router = api_router.merge(botserver::social::configure_social_routes());
|
2026-01-13 14:48:49 -03:00
|
|
|
api_router = api_router.merge(botserver::social::ui::configure_social_ui_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::email::ui::configure_email_ui_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::learn::ui::configure_learn_ui_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::meet::ui::configure_meet_ui_routes());
|
feat(api): add CRM, billing, products stub UI routes
- Add crm_ui.rs with stub handlers for pipeline, leads, contacts, accounts, stats
- Add billing_ui.rs with stub handlers for invoices, payments, quotes, stats
- Add products module with stub handlers for items, services, pricelists, stats
- Register routes in main.rs
These stubs return empty data/HTML to prevent 404 errors in UI.
Full CRUD implementation to follow.
2026-01-12 14:35:03 -03:00
|
|
|
api_router = api_router.merge(botserver::contacts::crm_ui::configure_crm_routes());
|
Implement database persistence for dashboards, legal, and compliance modules
- Add PostgreSQL persistence for dashboards module (was returning empty vec![])
- Tables: dashboards, dashboard_widgets, dashboard_data_sources, dashboard_filters,
dashboard_widget_data_sources, conversational_queries
- Full CRUD operations with spawn_blocking pattern
- Add PostgreSQL persistence for legal module (was using in-memory HashMap)
- Tables: legal_documents, legal_document_versions, cookie_consents, consent_history,
legal_acceptances, data_deletion_requests, data_export_requests
- GDPR-compliant consent tracking and document management
- Add PostgreSQL persistence for compliance module (was returning empty results)
- Tables: compliance_checks, compliance_issues, compliance_audit_log, compliance_evidence,
compliance_risk_assessments, compliance_risks, compliance_training_records,
compliance_access_reviews
- Support for GDPR, SOC2, ISO27001, HIPAA, PCI-DSS frameworks
- Add migration files for all new tables
- Update schema.rs with new table definitions and joinables
- Register new routes in main.rs
- Add recursion_limit = 512 for macro expansion
2026-01-13 00:07:22 -03:00
|
|
|
api_router = api_router.merge(botserver::contacts::crm::configure_crm_api_routes());
|
feat(api): add CRM, billing, products stub UI routes
- Add crm_ui.rs with stub handlers for pipeline, leads, contacts, accounts, stats
- Add billing_ui.rs with stub handlers for invoices, payments, quotes, stats
- Add products module with stub handlers for items, services, pricelists, stats
- Register routes in main.rs
These stubs return empty data/HTML to prevent 404 errors in UI.
Full CRUD implementation to follow.
2026-01-12 14:35:03 -03:00
|
|
|
api_router = api_router.merge(botserver::billing::billing_ui::configure_billing_routes());
|
Implement database persistence for dashboards, legal, and compliance modules
- Add PostgreSQL persistence for dashboards module (was returning empty vec![])
- Tables: dashboards, dashboard_widgets, dashboard_data_sources, dashboard_filters,
dashboard_widget_data_sources, conversational_queries
- Full CRUD operations with spawn_blocking pattern
- Add PostgreSQL persistence for legal module (was using in-memory HashMap)
- Tables: legal_documents, legal_document_versions, cookie_consents, consent_history,
legal_acceptances, data_deletion_requests, data_export_requests
- GDPR-compliant consent tracking and document management
- Add PostgreSQL persistence for compliance module (was returning empty results)
- Tables: compliance_checks, compliance_issues, compliance_audit_log, compliance_evidence,
compliance_risk_assessments, compliance_risks, compliance_training_records,
compliance_access_reviews
- Support for GDPR, SOC2, ISO27001, HIPAA, PCI-DSS frameworks
- Add migration files for all new tables
- Update schema.rs with new table definitions and joinables
- Register new routes in main.rs
- Add recursion_limit = 512 for macro expansion
2026-01-13 00:07:22 -03:00
|
|
|
api_router = api_router.merge(botserver::billing::api::configure_billing_api_routes());
|
feat(api): add CRM, billing, products stub UI routes
- Add crm_ui.rs with stub handlers for pipeline, leads, contacts, accounts, stats
- Add billing_ui.rs with stub handlers for invoices, payments, quotes, stats
- Add products module with stub handlers for items, services, pricelists, stats
- Register routes in main.rs
These stubs return empty data/HTML to prevent 404 errors in UI.
Full CRUD implementation to follow.
2026-01-12 14:35:03 -03:00
|
|
|
api_router = api_router.merge(botserver::products::configure_products_routes());
|
Implement database persistence for dashboards, legal, and compliance modules
- Add PostgreSQL persistence for dashboards module (was returning empty vec![])
- Tables: dashboards, dashboard_widgets, dashboard_data_sources, dashboard_filters,
dashboard_widget_data_sources, conversational_queries
- Full CRUD operations with spawn_blocking pattern
- Add PostgreSQL persistence for legal module (was using in-memory HashMap)
- Tables: legal_documents, legal_document_versions, cookie_consents, consent_history,
legal_acceptances, data_deletion_requests, data_export_requests
- GDPR-compliant consent tracking and document management
- Add PostgreSQL persistence for compliance module (was returning empty results)
- Tables: compliance_checks, compliance_issues, compliance_audit_log, compliance_evidence,
compliance_risk_assessments, compliance_risks, compliance_training_records,
compliance_access_reviews
- Support for GDPR, SOC2, ISO27001, HIPAA, PCI-DSS frameworks
- Add migration files for all new tables
- Update schema.rs with new table definitions and joinables
- Register new routes in main.rs
- Add recursion_limit = 512 for macro expansion
2026-01-13 00:07:22 -03:00
|
|
|
api_router = api_router.merge(botserver::products::api::configure_products_api_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::tickets::configure_tickets_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::tickets::ui::configure_tickets_ui_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::people::configure_people_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::people::ui::configure_people_ui_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::attendant::configure_attendant_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::attendant::ui::configure_attendant_ui_routes());
|
2025-11-29 16:29:28 -03:00
|
|
|
|
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
|
|
|
#[cfg(feature = "whatsapp")]
|
|
|
|
|
{
|
|
|
|
|
api_router = api_router.merge(crate::whatsapp::configure());
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-06 22:56:35 -03:00
|
|
|
#[cfg(feature = "telegram")]
|
|
|
|
|
{
|
|
|
|
|
api_router = api_router.merge(botserver::telegram::configure());
|
|
|
|
|
}
|
|
|
|
|
|
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
|
|
|
#[cfg(feature = "attendance")]
|
|
|
|
|
{
|
|
|
|
|
api_router = api_router.merge(crate::attendance::configure_attendance_routes());
|
|
|
|
|
}
|
|
|
|
|
|
feat(auth): Add OAuth login for Google, Discord, Reddit, Twitter, Microsoft, Facebook
- Create core/oauth module with OAuthProvider enum and shared types
- Implement providers.rs with auth URLs, token exchange, user info endpoints
- Add routes for /auth/oauth/providers, /auth/oauth/{provider}, and callbacks
- Update login.html with OAuth button grid and dynamic provider loading
- Add OAuth config settings to config.csv with setup documentation and links
- Uses HTMX for login form, minimal JS for OAuth provider visibility
2025-12-04 22:53:40 -03:00
|
|
|
api_router = api_router.merge(crate::core::oauth::routes::configure());
|
|
|
|
|
|
2025-12-17 17:41:37 -03:00
|
|
|
let site_path = app_state
|
|
|
|
|
.config
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|c| c.site_path.clone())
|
|
|
|
|
.unwrap_or_else(|| "./botserver-stack/sites".to_string());
|
|
|
|
|
|
|
|
|
|
info!("Serving apps from: {}", site_path);
|
|
|
|
|
|
feat(security): Complete security infrastructure implementation
SECURITY MODULES ADDED:
- security/auth.rs: Full RBAC with roles (Anonymous, User, Moderator, Admin, SuperAdmin, Service, Bot, BotOwner, BotOperator, BotViewer) and permissions
- security/cors.rs: Hardened CORS (no wildcard in production, env-based config)
- security/panic_handler.rs: Panic catching middleware with safe 500 responses
- security/path_guard.rs: Path traversal protection, null byte prevention
- security/request_id.rs: UUID request tracking with correlation IDs
- security/error_sanitizer.rs: Sensitive data redaction from responses
- security/zitadel_auth.rs: Zitadel token introspection and role mapping
- security/sql_guard.rs: SQL injection prevention with table whitelist
- security/command_guard.rs: Command injection prevention
- security/secrets.rs: Zeroizing secret management
- security/validation.rs: Input validation utilities
- security/rate_limiter.rs: Rate limiting with governor crate
- security/headers.rs: Security headers (CSP, HSTS, X-Frame-Options)
MAIN.RS UPDATES:
- Replaced tower_http::cors::Any with hardened create_cors_layer()
- Added panic handler middleware
- Added request ID tracking middleware
- Set global panic hook
SECURITY STATUS:
- 0 unwrap() in production code
- 0 panic! in production code
- 0 unsafe blocks
- cargo audit: PASS (no vulnerabilities)
- Estimated completion: ~98%
Remaining: Wire auth middleware to handlers, audit logs for sensitive data
2025-12-28 19:29:18 -03:00
|
|
|
// Create rate limiter integrating with botlib's RateLimiter
|
|
|
|
|
let http_rate_config = HttpRateLimitConfig::api();
|
|
|
|
|
let system_limits = SystemLimits::default();
|
|
|
|
|
let (rate_limit_extension, _rate_limiter) = create_rate_limit_layer(http_rate_config, system_limits);
|
|
|
|
|
|
|
|
|
|
// Create security headers layer
|
|
|
|
|
let security_headers_config = SecurityHeadersConfig::default();
|
|
|
|
|
let security_headers_extension = create_security_headers_layer(security_headers_config.clone());
|
|
|
|
|
|
|
|
|
|
// Determine panic handler config based on environment
|
|
|
|
|
let is_production = std::env::var("BOTSERVER_ENV")
|
|
|
|
|
.map(|v| v == "production" || v == "prod")
|
|
|
|
|
.unwrap_or(false);
|
|
|
|
|
let panic_config = if is_production {
|
|
|
|
|
PanicHandlerConfig::production()
|
|
|
|
|
} else {
|
|
|
|
|
PanicHandlerConfig::development()
|
|
|
|
|
};
|
|
|
|
|
|
feat(security): Complete security wiring and log audit
SECURITY WIRING:
- Auth middleware wired to main router with AnonymousPath config
- CORS allowed origins loaded from bot_configuration database (config.csv)
- Zitadel auth config loads from Vault via SecretsManager
- No more env vars for sensitive config (only VAULT_* allowed)
LOG AUDIT:
- Added is_sensitive_config_key() check in ask_later.rs
- Sensitive config values (password, secret, token, key, etc) now logged as [REDACTED]
- Removed potential credential exposure in pending_info logs
CONFIG LOADING ORDER:
1. VAULT_ADDR and VAULT_TOKEN from .env
2. All secrets from Vault (gbo/directory for Zitadel)
3. Bot config from config.csv (cors-allowed-origins, etc)
Auth Config Paths:
- Anonymous: /health, /healthz, /api/health, /ws, /auth
- Public: /static, /favicon.ico
2025-12-28 19:41:33 -03:00
|
|
|
info!("Security middleware enabled: rate limiting, security headers, panic handler, request ID tracking, authentication");
|
feat(security): Complete security infrastructure implementation
SECURITY MODULES ADDED:
- security/auth.rs: Full RBAC with roles (Anonymous, User, Moderator, Admin, SuperAdmin, Service, Bot, BotOwner, BotOperator, BotViewer) and permissions
- security/cors.rs: Hardened CORS (no wildcard in production, env-based config)
- security/panic_handler.rs: Panic catching middleware with safe 500 responses
- security/path_guard.rs: Path traversal protection, null byte prevention
- security/request_id.rs: UUID request tracking with correlation IDs
- security/error_sanitizer.rs: Sensitive data redaction from responses
- security/zitadel_auth.rs: Zitadel token introspection and role mapping
- security/sql_guard.rs: SQL injection prevention with table whitelist
- security/command_guard.rs: Command injection prevention
- security/secrets.rs: Zeroizing secret management
- security/validation.rs: Input validation utilities
- security/rate_limiter.rs: Rate limiting with governor crate
- security/headers.rs: Security headers (CSP, HSTS, X-Frame-Options)
MAIN.RS UPDATES:
- Replaced tower_http::cors::Any with hardened create_cors_layer()
- Added panic handler middleware
- Added request ID tracking middleware
- Set global panic hook
SECURITY STATUS:
- 0 unwrap() in production code
- 0 panic! in production code
- 0 unsafe blocks
- cargo audit: PASS (no vulnerabilities)
- Estimated completion: ~98%
Remaining: Wire auth middleware to handlers, audit logs for sensitive data
2025-12-28 19:29:18 -03:00
|
|
|
|
2026-01-09 19:19:41 -03:00
|
|
|
// Path to UI files (botui) - use external folder or fallback to embedded
|
2026-01-06 22:56:35 -03:00
|
|
|
let ui_path = std::env::var("BOTUI_PATH").unwrap_or_else(|_| "./botui/ui/suite".to_string());
|
2026-01-09 19:19:41 -03:00
|
|
|
let ui_path_exists = std::path::Path::new(&ui_path).exists();
|
|
|
|
|
let use_embedded_ui = !ui_path_exists && embedded_ui::has_embedded_ui();
|
|
|
|
|
|
|
|
|
|
if ui_path_exists {
|
|
|
|
|
info!("Serving UI from external folder: {}", ui_path);
|
|
|
|
|
} else if use_embedded_ui {
|
|
|
|
|
info!("External UI folder not found at '{}', using embedded UI", ui_path);
|
|
|
|
|
let file_count = embedded_ui::list_embedded_files().len();
|
|
|
|
|
info!("Embedded UI contains {} files", file_count);
|
|
|
|
|
} else {
|
|
|
|
|
warn!("No UI available: folder '{}' not found and no embedded UI", ui_path);
|
|
|
|
|
}
|
2026-01-06 22:56:35 -03:00
|
|
|
|
2026-01-10 09:41:12 -03:00
|
|
|
// Update app_state with auth components
|
|
|
|
|
let mut app_state_with_auth = (*app_state).clone();
|
|
|
|
|
app_state_with_auth.jwt_manager = jwt_manager;
|
|
|
|
|
app_state_with_auth.auth_provider_registry = Some(Arc::clone(&auth_provider_registry));
|
|
|
|
|
app_state_with_auth.rbac_manager = Some(Arc::clone(&rbac_manager));
|
|
|
|
|
let app_state = Arc::new(app_state_with_auth);
|
|
|
|
|
|
2026-01-09 19:19:41 -03:00
|
|
|
let base_router = Router::new()
|
2025-11-26 22:54:22 -03:00
|
|
|
.merge(api_router.with_state(app_state.clone()))
|
feat(autotask): Implement AutoTask system with intent classification and app generation
- Add IntentClassifier with 7 intent types (APP_CREATE, TODO, MONITOR, ACTION, SCHEDULE, GOAL, TOOL)
- Add AppGenerator with LLM-powered app structure analysis
- Add DesignerAI for modifying apps through conversation
- Add app_server for serving generated apps with clean URLs
- Add db_api for CRUD operations on bot database tables
- Add ask_later keyword for pending info collection
- Add migration 6.1.1 with tables: pending_info, auto_tasks, execution_plans, task_approvals, task_decisions, safety_audit_log, generated_apps, intent_classifications, designer_changes
- Write apps to S3 drive and sync to SITE_ROOT for serving
- Clean URL structure: /apps/{app_name}/
- Integrate with DriveMonitor for file sync
Based on Chapter 17 - Autonomous Tasks specification
2025-12-27 21:10:09 -03:00
|
|
|
// Static files fallback for legacy /apps/* paths
|
2026-01-09 19:19:41 -03:00
|
|
|
.nest_service("/static", ServeDir::new(&site_path));
|
|
|
|
|
|
|
|
|
|
// Add UI routes based on availability
|
|
|
|
|
let app_with_ui = if ui_path_exists {
|
|
|
|
|
base_router
|
|
|
|
|
.nest_service("/auth", ServeDir::new(format!("{}/auth", ui_path)))
|
|
|
|
|
.nest_service("/suite", ServeDir::new(&ui_path))
|
|
|
|
|
.nest_service("/themes", ServeDir::new(format!("{}/../themes", ui_path)))
|
|
|
|
|
.fallback_service(ServeDir::new(&ui_path))
|
|
|
|
|
} else if use_embedded_ui {
|
|
|
|
|
base_router
|
|
|
|
|
.merge(embedded_ui::embedded_ui_router())
|
|
|
|
|
} else {
|
|
|
|
|
base_router
|
|
|
|
|
};
|
|
|
|
|
|
feat(rbac): implement complete RBAC middleware and route permissions
- Add rbac_middleware_fn for use in middleware layer chain
- Add RBAC middleware to request processing pipeline (after auth)
- Complete route permissions for ALL apps:
- Anonymous: health, i18n, product, auth/login, chat, websocket
- Authenticated users: drive, mail, calendar, tasks, docs, paper, sheet,
slides, meet, research, sources, canvas, video, player, workspaces,
projects, goals, settings, bots (read), designer, dashboards, crm,
contacts, billing, products, tickets, learn, social, llm, autotask
- Admin/SuperAdmin: users, groups, bot management, analytics, monitoring,
audit, security, admin panel, attendant
- SuperAdmin only: RBAC management
- Add all /api/ui/** HTMX routes with proper permissions
- Chat remains anonymous for customer support functionality
2026-01-10 11:41:25 -03:00
|
|
|
// Clone rbac_manager for use in middleware
|
|
|
|
|
let rbac_manager_for_middleware = Arc::clone(&rbac_manager);
|
|
|
|
|
|
2026-01-09 19:19:41 -03:00
|
|
|
let app = app_with_ui
|
2026-01-10 17:31:50 -03:00
|
|
|
// Security middleware stack (order matters - last added is outermost/runs first)
|
feat(security): Complete security infrastructure implementation
SECURITY MODULES ADDED:
- security/auth.rs: Full RBAC with roles (Anonymous, User, Moderator, Admin, SuperAdmin, Service, Bot, BotOwner, BotOperator, BotViewer) and permissions
- security/cors.rs: Hardened CORS (no wildcard in production, env-based config)
- security/panic_handler.rs: Panic catching middleware with safe 500 responses
- security/path_guard.rs: Path traversal protection, null byte prevention
- security/request_id.rs: UUID request tracking with correlation IDs
- security/error_sanitizer.rs: Sensitive data redaction from responses
- security/zitadel_auth.rs: Zitadel token introspection and role mapping
- security/sql_guard.rs: SQL injection prevention with table whitelist
- security/command_guard.rs: Command injection prevention
- security/secrets.rs: Zeroizing secret management
- security/validation.rs: Input validation utilities
- security/rate_limiter.rs: Rate limiting with governor crate
- security/headers.rs: Security headers (CSP, HSTS, X-Frame-Options)
MAIN.RS UPDATES:
- Replaced tower_http::cors::Any with hardened create_cors_layer()
- Added panic handler middleware
- Added request ID tracking middleware
- Set global panic hook
SECURITY STATUS:
- 0 unwrap() in production code
- 0 panic! in production code
- 0 unsafe blocks
- cargo audit: PASS (no vulnerabilities)
- Estimated completion: ~98%
Remaining: Wire auth middleware to handlers, audit logs for sensitive data
2025-12-28 19:29:18 -03:00
|
|
|
.layer(middleware::from_fn(security_headers_middleware))
|
|
|
|
|
.layer(security_headers_extension)
|
|
|
|
|
.layer(rate_limit_extension)
|
|
|
|
|
// Request ID tracking for all requests
|
|
|
|
|
.layer(middleware::from_fn(request_id_middleware))
|
2026-01-10 17:31:50 -03:00
|
|
|
// RBAC middleware - checks permissions AFTER authentication
|
|
|
|
|
// NOTE: In Axum, layers run in reverse order (last added = first to run)
|
|
|
|
|
// So RBAC is added BEFORE auth, meaning auth runs first, then RBAC
|
feat(rbac): implement complete RBAC middleware and route permissions
- Add rbac_middleware_fn for use in middleware layer chain
- Add RBAC middleware to request processing pipeline (after auth)
- Complete route permissions for ALL apps:
- Anonymous: health, i18n, product, auth/login, chat, websocket
- Authenticated users: drive, mail, calendar, tasks, docs, paper, sheet,
slides, meet, research, sources, canvas, video, player, workspaces,
projects, goals, settings, bots (read), designer, dashboards, crm,
contacts, billing, products, tickets, learn, social, llm, autotask
- Admin/SuperAdmin: users, groups, bot management, analytics, monitoring,
audit, security, admin panel, attendant
- SuperAdmin only: RBAC management
- Add all /api/ui/** HTMX routes with proper permissions
- Chat remains anonymous for customer support functionality
2026-01-10 11:41:25 -03:00
|
|
|
.layer(middleware::from_fn(move |req: axum::http::Request<axum::body::Body>, next: axum::middleware::Next| {
|
2026-01-10 17:31:50 -03:00
|
|
|
let rbac = Arc::clone(&rbac_manager_for_middleware);
|
feat(rbac): implement complete RBAC middleware and route permissions
- Add rbac_middleware_fn for use in middleware layer chain
- Add RBAC middleware to request processing pipeline (after auth)
- Complete route permissions for ALL apps:
- Anonymous: health, i18n, product, auth/login, chat, websocket
- Authenticated users: drive, mail, calendar, tasks, docs, paper, sheet,
slides, meet, research, sources, canvas, video, player, workspaces,
projects, goals, settings, bots (read), designer, dashboards, crm,
contacts, billing, products, tickets, learn, social, llm, autotask
- Admin/SuperAdmin: users, groups, bot management, analytics, monitoring,
audit, security, admin panel, attendant
- SuperAdmin only: RBAC management
- Add all /api/ui/** HTMX routes with proper permissions
- Chat remains anonymous for customer support functionality
2026-01-10 11:41:25 -03:00
|
|
|
async move {
|
2026-01-10 17:31:50 -03:00
|
|
|
botserver::security::rbac_middleware_fn(req, next, rbac).await
|
feat(rbac): implement complete RBAC middleware and route permissions
- Add rbac_middleware_fn for use in middleware layer chain
- Add RBAC middleware to request processing pipeline (after auth)
- Complete route permissions for ALL apps:
- Anonymous: health, i18n, product, auth/login, chat, websocket
- Authenticated users: drive, mail, calendar, tasks, docs, paper, sheet,
slides, meet, research, sources, canvas, video, player, workspaces,
projects, goals, settings, bots (read), designer, dashboards, crm,
contacts, billing, products, tickets, learn, social, llm, autotask
- Admin/SuperAdmin: users, groups, bot management, analytics, monitoring,
audit, security, admin panel, attendant
- SuperAdmin only: RBAC management
- Add all /api/ui/** HTMX routes with proper permissions
- Chat remains anonymous for customer support functionality
2026-01-10 11:41:25 -03:00
|
|
|
}
|
|
|
|
|
}))
|
2026-01-10 17:31:50 -03:00
|
|
|
// Authentication middleware - MUST run before RBAC (so added after)
|
2026-01-10 09:41:12 -03:00
|
|
|
.layer(middleware::from_fn(move |req: axum::http::Request<axum::body::Body>, next: axum::middleware::Next| {
|
2026-01-10 17:31:50 -03:00
|
|
|
let state = auth_middleware_state.clone();
|
2026-01-10 09:41:12 -03:00
|
|
|
async move {
|
2026-01-10 17:31:50 -03:00
|
|
|
botserver::security::auth_middleware_with_providers(req, next, state).await
|
2026-01-10 09:41:12 -03:00
|
|
|
}
|
|
|
|
|
}))
|
feat(security): Complete security infrastructure implementation
SECURITY MODULES ADDED:
- security/auth.rs: Full RBAC with roles (Anonymous, User, Moderator, Admin, SuperAdmin, Service, Bot, BotOwner, BotOperator, BotViewer) and permissions
- security/cors.rs: Hardened CORS (no wildcard in production, env-based config)
- security/panic_handler.rs: Panic catching middleware with safe 500 responses
- security/path_guard.rs: Path traversal protection, null byte prevention
- security/request_id.rs: UUID request tracking with correlation IDs
- security/error_sanitizer.rs: Sensitive data redaction from responses
- security/zitadel_auth.rs: Zitadel token introspection and role mapping
- security/sql_guard.rs: SQL injection prevention with table whitelist
- security/command_guard.rs: Command injection prevention
- security/secrets.rs: Zeroizing secret management
- security/validation.rs: Input validation utilities
- security/rate_limiter.rs: Rate limiting with governor crate
- security/headers.rs: Security headers (CSP, HSTS, X-Frame-Options)
MAIN.RS UPDATES:
- Replaced tower_http::cors::Any with hardened create_cors_layer()
- Added panic handler middleware
- Added request ID tracking middleware
- Set global panic hook
SECURITY STATUS:
- 0 unwrap() in production code
- 0 panic! in production code
- 0 unsafe blocks
- cargo audit: PASS (no vulnerabilities)
- Estimated completion: ~98%
Remaining: Wire auth middleware to handlers, audit logs for sensitive data
2025-12-28 19:29:18 -03:00
|
|
|
// Panic handler catches panics and returns safe 500 responses
|
|
|
|
|
.layer(middleware::from_fn(move |req, next| {
|
|
|
|
|
let config = panic_config.clone();
|
|
|
|
|
async move {
|
|
|
|
|
botserver::security::panic_handler_middleware_with_config(req, next, &config).await
|
|
|
|
|
}
|
|
|
|
|
}))
|
2025-11-28 15:06:30 -03:00
|
|
|
.layer(Extension(app_state.clone()))
|
2025-11-20 13:28:35 -03:00
|
|
|
.layer(cors)
|
|
|
|
|
.layer(TraceLayer::new_for_http());
|
|
|
|
|
|
2025-11-29 16:29:28 -03:00
|
|
|
let cert_dir = std::path::Path::new("./botserver-stack/conf/system/certificates");
|
|
|
|
|
let cert_path = cert_dir.join("api/server.crt");
|
|
|
|
|
let key_path = cert_dir.join("api/server.key");
|
|
|
|
|
|
2025-11-20 13:28:35 -03:00
|
|
|
let addr = SocketAddr::from(([0, 0, 0, 0], port));
|
|
|
|
|
|
2025-12-08 14:08:49 -03:00
|
|
|
let disable_tls = std::env::var("BOTSERVER_DISABLE_TLS")
|
|
|
|
|
.map(|v| v == "true" || v == "1")
|
|
|
|
|
.unwrap_or(false);
|
|
|
|
|
|
|
|
|
|
if !disable_tls && cert_path.exists() && key_path.exists() {
|
2025-11-29 16:29:28 -03:00
|
|
|
let tls_config = axum_server::tls_rustls::RustlsConfig::from_pem_file(cert_path, key_path)
|
|
|
|
|
.await
|
2025-12-26 08:59:25 -03:00
|
|
|
.map_err(std::io::Error::other)?;
|
2025-11-20 13:28:35 -03:00
|
|
|
|
2025-11-29 16:29:28 -03:00
|
|
|
info!("HTTPS server listening on {} with TLS", addr);
|
|
|
|
|
|
2025-12-02 21:09:43 -03:00
|
|
|
let handle = axum_server::Handle::new();
|
2025-12-10 18:31:58 -03:00
|
|
|
let handle_clone = handle.clone();
|
|
|
|
|
|
|
|
|
|
tokio::spawn(async move {
|
|
|
|
|
shutdown_signal().await;
|
|
|
|
|
info!("Shutting down HTTPS server...");
|
|
|
|
|
handle_clone.graceful_shutdown(Some(std::time::Duration::from_secs(10)));
|
|
|
|
|
});
|
|
|
|
|
|
2025-11-29 16:29:28 -03:00
|
|
|
axum_server::bind_rustls(addr, tls_config)
|
2025-12-02 21:09:43 -03:00
|
|
|
.handle(handle)
|
2025-11-29 16:29:28 -03:00
|
|
|
.serve(app.into_make_service())
|
|
|
|
|
.await
|
2025-12-29 08:45:46 -03:00
|
|
|
.map_err(|e| {
|
|
|
|
|
error!("HTTPS server failed on {}: {}", addr, e);
|
|
|
|
|
e
|
|
|
|
|
})
|
2025-11-29 16:29:28 -03:00
|
|
|
} else {
|
2025-12-08 14:08:49 -03:00
|
|
|
if disable_tls {
|
|
|
|
|
info!("TLS disabled via BOTSERVER_DISABLE_TLS environment variable");
|
|
|
|
|
} else {
|
|
|
|
|
warn!("TLS certificates not found, using HTTP");
|
|
|
|
|
}
|
2025-11-29 16:29:28 -03:00
|
|
|
|
2025-12-29 08:45:46 -03:00
|
|
|
let listener = match tokio::net::TcpListener::bind(addr).await {
|
|
|
|
|
Ok(l) => l,
|
|
|
|
|
Err(e) => {
|
|
|
|
|
error!("Failed to bind to {}: {} - is another instance running?", addr, e);
|
|
|
|
|
return Err(e);
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-12-08 14:08:49 -03:00
|
|
|
info!("HTTP server listening on {}", addr);
|
2025-11-29 16:29:28 -03:00
|
|
|
axum::serve(listener, app.into_make_service())
|
2025-12-10 18:31:58 -03:00
|
|
|
.with_graceful_shutdown(shutdown_signal())
|
2025-11-29 16:29:28 -03:00
|
|
|
.await
|
2025-12-26 08:59:25 -03:00
|
|
|
.map_err(std::io::Error::other)
|
2025-11-29 16:29:28 -03:00
|
|
|
}
|
2025-11-19 14:00:57 -03:00
|
|
|
}
|
|
|
|
|
|
2025-10-19 14:02:47 -03:00
|
|
|
#[tokio::main]
|
2025-10-16 11:43:02 -03:00
|
|
|
async fn main() -> std::io::Result<()> {
|
feat(security): Complete security infrastructure implementation
SECURITY MODULES ADDED:
- security/auth.rs: Full RBAC with roles (Anonymous, User, Moderator, Admin, SuperAdmin, Service, Bot, BotOwner, BotOperator, BotViewer) and permissions
- security/cors.rs: Hardened CORS (no wildcard in production, env-based config)
- security/panic_handler.rs: Panic catching middleware with safe 500 responses
- security/path_guard.rs: Path traversal protection, null byte prevention
- security/request_id.rs: UUID request tracking with correlation IDs
- security/error_sanitizer.rs: Sensitive data redaction from responses
- security/zitadel_auth.rs: Zitadel token introspection and role mapping
- security/sql_guard.rs: SQL injection prevention with table whitelist
- security/command_guard.rs: Command injection prevention
- security/secrets.rs: Zeroizing secret management
- security/validation.rs: Input validation utilities
- security/rate_limiter.rs: Rate limiting with governor crate
- security/headers.rs: Security headers (CSP, HSTS, X-Frame-Options)
MAIN.RS UPDATES:
- Replaced tower_http::cors::Any with hardened create_cors_layer()
- Added panic handler middleware
- Added request ID tracking middleware
- Set global panic hook
SECURITY STATUS:
- 0 unwrap() in production code
- 0 panic! in production code
- 0 unsafe blocks
- cargo audit: PASS (no vulnerabilities)
- Estimated completion: ~98%
Remaining: Wire auth middleware to handlers, audit logs for sensitive data
2025-12-28 19:29:18 -03:00
|
|
|
// Set global panic hook to log panics that escape async boundaries
|
|
|
|
|
set_global_panic_hook();
|
|
|
|
|
|
2025-12-08 23:35:33 -03:00
|
|
|
let args: Vec<String> = std::env::args().collect();
|
|
|
|
|
let no_ui = args.contains(&"--noui".to_string());
|
|
|
|
|
let no_console = args.contains(&"--noconsole".to_string());
|
|
|
|
|
|
2025-12-07 02:13:28 -03:00
|
|
|
let _ = rustls::crypto::ring::default_provider().install_default();
|
|
|
|
|
|
|
|
|
|
dotenvy::dotenv().ok();
|
|
|
|
|
|
2025-12-09 08:10:47 -03:00
|
|
|
let env_path_early = std::path::Path::new("./.env");
|
|
|
|
|
let vault_init_path_early = std::path::Path::new("./botserver-stack/conf/vault/init.json");
|
|
|
|
|
let bootstrap_ready = env_path_early.exists() && vault_init_path_early.exists() && {
|
|
|
|
|
std::fs::read_to_string(env_path_early)
|
|
|
|
|
.map(|content| content.contains("VAULT_TOKEN="))
|
|
|
|
|
.unwrap_or(false)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if bootstrap_ready {
|
|
|
|
|
if let Err(e) = crate::shared::utils::init_secrets_manager().await {
|
|
|
|
|
warn!(
|
|
|
|
|
"Failed to initialize SecretsManager: {}. Falling back to env vars.",
|
|
|
|
|
e
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
info!("SecretsManager initialized - fetching secrets from Vault");
|
|
|
|
|
}
|
2025-12-07 02:13:28 -03:00
|
|
|
} else {
|
2025-12-09 08:10:47 -03:00
|
|
|
trace!("Bootstrap not complete - skipping early SecretsManager init");
|
2025-12-07 02:13:28 -03:00
|
|
|
}
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
|
2026-01-11 20:10:23 -03:00
|
|
|
let noise_filters =
|
MS Office 100% Compatibility - Phase 1 Implementation
- Add rust_xlsxwriter for Excel export with formatting support
- Add docx-rs for Word document import/export with HTML conversion
- Add PPTX export support with slides, shapes, and text elements
- Refactor sheet module into 7 files (types, formulas, handlers, etc)
- Refactor docs module into 6 files (types, handlers, storage, etc)
- Refactor slides module into 6 files (types, handlers, storage, etc)
- Fix collaboration modules (borrow issues, rand compatibility)
- Add ooxmlsdk dependency for future Office 2021 features
- Fix type mismatches in slides storage
- Update security protection API router type
Features:
- Excel: Read xlsx/xlsm/xls, write xlsx with styles
- Word: Read/write docx with formatting preservation
- PowerPoint: Write pptx with slides, shapes, text
- Real-time collaboration via WebSocket (already working)
- Theme-aware UI with --sentient-* CSS variables
2026-01-11 09:56:15 -03:00
|
|
|
"vaultrs=off,rustify=off,rustify_derive=off,\
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
aws_sigv4=off,aws_smithy_checksums=off,aws_runtime=off,aws_smithy_http_client=off,\
|
|
|
|
|
aws_smithy_runtime=off,aws_smithy_runtime_api=off,aws_sdk_s3=off,aws_config=off,\
|
|
|
|
|
aws_credential_types=off,aws_http=off,aws_sig_auth=off,aws_types=off,\
|
|
|
|
|
mio=off,tokio=off,tokio_util=off,tower=off,tower_http=off,\
|
|
|
|
|
reqwest=off,hyper=off,hyper_util=off,h2=off,\
|
|
|
|
|
rustls=off,rustls_pemfile=off,tokio_rustls=off,\
|
|
|
|
|
tracing=off,tracing_core=off,tracing_subscriber=off,\
|
2025-11-28 13:50:28 -03:00
|
|
|
diesel=off,diesel_migrations=off,r2d2=warn,\
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
serde=off,serde_json=off,\
|
|
|
|
|
axum=off,axum_core=off,\
|
|
|
|
|
tonic=off,prost=off,\
|
|
|
|
|
lettre=off,imap=off,mailparse=off,\
|
|
|
|
|
crossterm=off,ratatui=off,\
|
|
|
|
|
tauri=off,tauri_runtime=off,tauri_utils=off,\
|
|
|
|
|
notify=off,ignore=off,walkdir=off,\
|
|
|
|
|
want=off,try_lock=off,futures=off,\
|
|
|
|
|
base64=off,bytes=off,encoding_rs=off,\
|
|
|
|
|
url=off,percent_encoding=off,\
|
|
|
|
|
ring=off,webpki=off,\
|
2026-01-11 20:10:23 -03:00
|
|
|
hickory_resolver=off,hickory_proto=off";
|
|
|
|
|
|
|
|
|
|
let rust_log = match std::env::var("RUST_LOG") {
|
|
|
|
|
Ok(existing) if !existing.is_empty() => format!("{},{}", existing, noise_filters),
|
|
|
|
|
_ => noise_filters.to_string(),
|
2025-12-02 21:09:43 -03:00
|
|
|
};
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
|
|
|
|
|
std::env::set_var("RUST_LOG", &rust_log);
|
|
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
use crate::llm::local::ensure_llama_servers_running;
|
|
|
|
|
use botserver::config::ConfigManager;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-08 23:35:33 -03:00
|
|
|
if no_console || no_ui {
|
2026-01-09 13:03:26 -03:00
|
|
|
botlib::logging::init_compact_logger_with_style("info");
|
2025-12-26 08:59:25 -03:00
|
|
|
println!("Starting General Bots {}...", env!("CARGO_PKG_VERSION"));
|
2025-12-08 23:35:33 -03:00
|
|
|
}
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2026-01-06 22:56:35 -03:00
|
|
|
let locales_path = if std::path::Path::new("./locales").exists() {
|
|
|
|
|
"./locales"
|
|
|
|
|
} else if std::path::Path::new("../botlib/locales").exists() {
|
|
|
|
|
"../botlib/locales"
|
|
|
|
|
} else if std::path::Path::new("../locales").exists() {
|
|
|
|
|
"../locales"
|
|
|
|
|
} else {
|
|
|
|
|
"./locales"
|
|
|
|
|
};
|
|
|
|
|
if let Err(e) = crate::core::i18n::init_i18n(locales_path) {
|
|
|
|
|
warn!("Failed to initialize i18n from {}: {}. Translations will show keys.", locales_path, e);
|
|
|
|
|
} else {
|
|
|
|
|
info!("i18n initialized from {} with locales: {:?}", locales_path, crate::core::i18n::available_locales());
|
|
|
|
|
}
|
|
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
let (progress_tx, _progress_rx) = tokio::sync::mpsc::unbounded_channel::<BootstrapProgress>();
|
|
|
|
|
let (state_tx, _state_rx) = tokio::sync::mpsc::channel::<Arc<AppState>>(1);
|
2025-11-15 09:48:46 -03:00
|
|
|
|
2025-11-15 19:08:26 -03:00
|
|
|
if args.len() > 1 {
|
|
|
|
|
let command = &args[1];
|
|
|
|
|
match command.as_str() {
|
2025-11-20 13:28:35 -03:00
|
|
|
"install" | "remove" | "list" | "status" | "start" | "stop" | "restart" | "--help"
|
|
|
|
|
| "-h" => match package_manager::cli::run().await {
|
2025-11-15 19:08:26 -03:00
|
|
|
Ok(_) => return Ok(()),
|
|
|
|
|
Err(e) => {
|
2025-12-26 08:59:25 -03:00
|
|
|
eprintln!("CLI error: {e}");
|
|
|
|
|
return Err(std::io::Error::other(format!("CLI command failed: {e}")));
|
2025-11-15 19:08:26 -03:00
|
|
|
}
|
|
|
|
|
},
|
2025-11-19 14:00:57 -03:00
|
|
|
_ => {}
|
2025-11-15 19:08:26 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-07 02:13:28 -03:00
|
|
|
let ui_handle: Option<std::thread::JoinHandle<()>> = if !no_console && !no_ui {
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
#[cfg(feature = "console")]
|
|
|
|
|
{
|
|
|
|
|
let progress_rx = Arc::new(tokio::sync::Mutex::new(_progress_rx));
|
|
|
|
|
let state_rx = Arc::new(tokio::sync::Mutex::new(_state_rx));
|
|
|
|
|
|
|
|
|
|
Some(
|
|
|
|
|
std::thread::Builder::new()
|
|
|
|
|
.name("ui-thread".to_string())
|
|
|
|
|
.spawn(move || {
|
2025-11-22 22:54:45 -03:00
|
|
|
let mut ui = botserver::console::XtreeUI::new();
|
2025-12-26 08:59:25 -03:00
|
|
|
ui.set_progress_channel(progress_rx);
|
|
|
|
|
ui.set_state_channel(state_rx);
|
2025-12-23 18:40:58 -03:00
|
|
|
|
2025-11-22 22:54:45 -03:00
|
|
|
if let Err(e) = ui.start_ui() {
|
2025-12-26 08:59:25 -03:00
|
|
|
eprintln!("UI error: {e}");
|
2025-11-22 22:54:45 -03:00
|
|
|
}
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
})
|
2025-12-28 21:26:08 -03:00
|
|
|
.map_err(|e| std::io::Error::other(format!("Failed to spawn UI thread: {}", e)))?,
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
#[cfg(not(feature = "console"))]
|
|
|
|
|
{
|
2025-11-28 13:50:28 -03:00
|
|
|
if !no_console {
|
|
|
|
|
eprintln!("Console feature not compiled. Rebuild with --features console or use --noconsole to suppress this message");
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
}
|
|
|
|
|
None
|
|
|
|
|
}
|
2025-11-11 09:42:52 -03:00
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let install_mode = if args.contains(&"--container".to_string()) {
|
|
|
|
|
InstallMode::Container
|
|
|
|
|
} else {
|
|
|
|
|
InstallMode::Local
|
|
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let tenant = if let Some(idx) = args.iter().position(|a| a == "--tenant") {
|
|
|
|
|
args.get(idx + 1).cloned()
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-06 14:55:42 -03:00
|
|
|
if let Some(idx) = args.iter().position(|a| a == "--stack-path") {
|
|
|
|
|
if let Some(path) = args.get(idx + 1) {
|
|
|
|
|
std::env::set_var("BOTSERVER_STACK_PATH", path);
|
|
|
|
|
info!("Using custom stack path: {}", path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Starting bootstrap process...");
|
2025-11-11 09:42:52 -03:00
|
|
|
let progress_tx_clone = progress_tx.clone();
|
|
|
|
|
let cfg = {
|
|
|
|
|
progress_tx_clone
|
|
|
|
|
.send(BootstrapProgress::StartingBootstrap)
|
|
|
|
|
.ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Creating BootstrapManager...");
|
2025-12-26 08:59:25 -03:00
|
|
|
let mut bootstrap = BootstrapManager::new(install_mode.clone(), tenant.clone());
|
2025-12-23 18:40:58 -03:00
|
|
|
|
2025-12-08 00:19:29 -03:00
|
|
|
let env_path = std::path::Path::new("./.env");
|
|
|
|
|
let vault_init_path = std::path::Path::new("./botserver-stack/conf/vault/init.json");
|
|
|
|
|
let bootstrap_completed = env_path.exists() && vault_init_path.exists() && {
|
|
|
|
|
std::fs::read_to_string(env_path)
|
|
|
|
|
.map(|content| content.contains("VAULT_TOKEN="))
|
|
|
|
|
.unwrap_or(false)
|
|
|
|
|
};
|
2025-11-29 17:27:13 -03:00
|
|
|
|
2025-12-09 08:26:29 -03:00
|
|
|
info!(
|
|
|
|
|
"Bootstrap check: .env exists={}, init.json exists={}, bootstrap_completed={}",
|
|
|
|
|
env_path.exists(),
|
|
|
|
|
vault_init_path.exists(),
|
|
|
|
|
bootstrap_completed
|
|
|
|
|
);
|
|
|
|
|
|
2025-12-08 00:19:29 -03:00
|
|
|
let cfg = if bootstrap_completed {
|
2025-12-09 08:26:29 -03:00
|
|
|
info!(">>> BRANCH: bootstrap_completed=TRUE - starting services only");
|
2025-11-29 17:27:13 -03:00
|
|
|
trace!("Services already configured, ensuring all are running...");
|
2025-11-28 13:50:28 -03:00
|
|
|
info!("Ensuring database and drive services are running...");
|
2025-11-11 15:01:57 -03:00
|
|
|
progress_tx_clone
|
|
|
|
|
.send(BootstrapProgress::StartingComponent(
|
|
|
|
|
"all services".to_string(),
|
|
|
|
|
))
|
|
|
|
|
.ok();
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Calling bootstrap.start_all()...");
|
2025-12-26 08:59:25 -03:00
|
|
|
bootstrap.start_all().await.map_err(std::io::Error::other)?;
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("bootstrap.start_all() completed");
|
2025-11-11 15:01:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Connecting to database...");
|
2025-11-11 09:42:52 -03:00
|
|
|
progress_tx_clone
|
|
|
|
|
.send(BootstrapProgress::ConnectingDatabase)
|
|
|
|
|
.ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Creating database connection...");
|
2025-11-11 09:42:52 -03:00
|
|
|
match create_conn() {
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
Ok(pool) => {
|
|
|
|
|
trace!("Database connection successful, loading config from database");
|
2025-12-28 21:26:08 -03:00
|
|
|
AppConfig::from_database(&pool).unwrap_or_else(|e| {
|
|
|
|
|
warn!("Failed to load config from database: {}, trying env", e);
|
|
|
|
|
AppConfig::from_env().unwrap_or_else(|env_e| {
|
|
|
|
|
error!("Failed to load config from env: {}", env_e);
|
|
|
|
|
AppConfig::default()
|
|
|
|
|
})
|
|
|
|
|
})
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
}
|
|
|
|
|
Err(e) => {
|
|
|
|
|
trace!(
|
|
|
|
|
"Database connection failed: {:?}, loading config from env",
|
|
|
|
|
e
|
|
|
|
|
);
|
2025-12-28 21:26:08 -03:00
|
|
|
AppConfig::from_env().unwrap_or_else(|e| {
|
|
|
|
|
error!("Failed to load config from env: {}", e);
|
|
|
|
|
AppConfig::default()
|
|
|
|
|
})
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
}
|
2025-10-18 19:08:00 -03:00
|
|
|
}
|
2025-11-11 09:42:52 -03:00
|
|
|
} else {
|
2025-12-09 08:26:29 -03:00
|
|
|
info!(">>> BRANCH: bootstrap_completed=FALSE - running full bootstrap");
|
2025-12-09 08:10:47 -03:00
|
|
|
info!("Bootstrap not complete - running full bootstrap...");
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!(".env file not found, running bootstrap.bootstrap()...");
|
2025-12-09 08:10:47 -03:00
|
|
|
if let Err(e) = bootstrap.bootstrap().await {
|
|
|
|
|
error!("Bootstrap failed: {}", e);
|
2025-12-26 08:59:25 -03:00
|
|
|
return Err(std::io::Error::other(format!("Bootstrap failed: {e}")));
|
2025-12-09 08:10:47 -03:00
|
|
|
}
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("bootstrap.bootstrap() completed");
|
2025-11-11 15:01:57 -03:00
|
|
|
progress_tx_clone
|
|
|
|
|
.send(BootstrapProgress::StartingComponent(
|
|
|
|
|
"all services".to_string(),
|
|
|
|
|
))
|
|
|
|
|
.ok();
|
2025-12-26 08:59:25 -03:00
|
|
|
bootstrap.start_all().await.map_err(std::io::Error::other)?;
|
2025-11-11 11:12:54 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
match create_conn() {
|
2025-12-28 21:26:08 -03:00
|
|
|
Ok(pool) => AppConfig::from_database(&pool).unwrap_or_else(|e| {
|
|
|
|
|
warn!("Failed to load config from database: {}, trying env", e);
|
|
|
|
|
AppConfig::from_env().unwrap_or_else(|env_e| {
|
|
|
|
|
error!("Failed to load config from env: {}", env_e);
|
|
|
|
|
AppConfig::default()
|
|
|
|
|
})
|
|
|
|
|
}),
|
|
|
|
|
Err(_) => AppConfig::from_env().unwrap_or_else(|e| {
|
|
|
|
|
error!("Failed to load config from env: {}", e);
|
|
|
|
|
AppConfig::default()
|
|
|
|
|
}),
|
2025-11-11 09:42:52 -03:00
|
|
|
}
|
|
|
|
|
};
|
2025-11-11 15:01:57 -03:00
|
|
|
|
2025-12-08 00:19:29 -03:00
|
|
|
trace!("Config loaded, syncing templates to database...");
|
2025-11-11 09:42:52 -03:00
|
|
|
progress_tx_clone
|
|
|
|
|
.send(BootstrapProgress::UploadingTemplates)
|
|
|
|
|
.ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-08 00:19:29 -03:00
|
|
|
if let Err(e) = bootstrap.sync_templates_to_database() {
|
|
|
|
|
warn!("Failed to sync templates to database: {}", e);
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
} else {
|
2025-12-08 00:19:29 -03:00
|
|
|
trace!("Templates synced to database");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
match tokio::time::timeout(
|
|
|
|
|
std::time::Duration::from_secs(30),
|
|
|
|
|
bootstrap.upload_templates_to_drive(&cfg),
|
|
|
|
|
)
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(Ok(_)) => {
|
|
|
|
|
trace!("Templates uploaded to drive successfully");
|
|
|
|
|
}
|
|
|
|
|
Ok(Err(e)) => {
|
|
|
|
|
warn!("Template drive upload error (non-blocking): {}", e);
|
|
|
|
|
}
|
|
|
|
|
Err(_) => {
|
|
|
|
|
warn!("Template drive upload timed out after 30s, continuing startup...");
|
|
|
|
|
}
|
2025-10-18 19:08:00 -03:00
|
|
|
}
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
Ok::<AppConfig, std::io::Error>(cfg)
|
2025-10-18 19:08:00 -03:00
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Bootstrap config phase complete");
|
2025-11-11 09:42:52 -03:00
|
|
|
let cfg = cfg?;
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Reloading dotenv...");
|
2025-11-11 09:42:52 -03:00
|
|
|
dotenv().ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Creating database pool again...");
|
2025-11-11 09:42:52 -03:00
|
|
|
progress_tx.send(BootstrapProgress::ConnectingDatabase).ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let pool = match create_conn() {
|
2025-11-28 13:50:28 -03:00
|
|
|
Ok(pool) => {
|
|
|
|
|
trace!("Running database migrations...");
|
|
|
|
|
info!("Running database migrations...");
|
|
|
|
|
if let Err(e) = crate::shared::utils::run_migrations(&pool) {
|
|
|
|
|
error!("Failed to run migrations: {}", e);
|
2025-12-23 18:40:58 -03:00
|
|
|
|
2025-11-28 13:50:28 -03:00
|
|
|
warn!("Continuing despite migration errors - database might be partially migrated");
|
|
|
|
|
} else {
|
|
|
|
|
info!("Database migrations completed successfully");
|
|
|
|
|
}
|
|
|
|
|
pool
|
|
|
|
|
}
|
2025-11-11 09:42:52 -03:00
|
|
|
Err(e) => {
|
|
|
|
|
error!("Failed to create database pool: {}", e);
|
|
|
|
|
progress_tx
|
|
|
|
|
.send(BootstrapProgress::BootstrapError(format!(
|
|
|
|
|
"Database pool creation failed: {}",
|
|
|
|
|
e
|
|
|
|
|
)))
|
|
|
|
|
.ok();
|
|
|
|
|
return Err(std::io::Error::new(
|
|
|
|
|
std::io::ErrorKind::ConnectionRefused,
|
|
|
|
|
format!("Database pool creation failed: {}", e),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-08 00:19:29 -03:00
|
|
|
info!("Loading config from database after template sync...");
|
|
|
|
|
let refreshed_cfg = AppConfig::from_database(&pool).unwrap_or_else(|e| {
|
|
|
|
|
warn!(
|
|
|
|
|
"Failed to load config from database: {}, falling back to env",
|
|
|
|
|
e
|
|
|
|
|
);
|
2025-12-28 21:26:08 -03:00
|
|
|
AppConfig::from_env().unwrap_or_else(|e| {
|
|
|
|
|
error!("Failed to load config from env: {}", e);
|
|
|
|
|
AppConfig::default()
|
|
|
|
|
})
|
2025-12-08 00:19:29 -03:00
|
|
|
});
|
|
|
|
|
let config = std::sync::Arc::new(refreshed_cfg.clone());
|
|
|
|
|
info!(
|
|
|
|
|
"Server configured to listen on {}:{}",
|
|
|
|
|
config.server.host, config.server.port
|
|
|
|
|
);
|
|
|
|
|
|
2025-12-08 23:35:33 -03:00
|
|
|
let cache_url = "redis://localhost:6379".to_string();
|
2025-11-11 09:42:52 -03:00
|
|
|
let redis_client = match redis::Client::open(cache_url.as_str()) {
|
|
|
|
|
Ok(client) => Some(Arc::new(client)),
|
|
|
|
|
Err(e) => {
|
|
|
|
|
log::warn!("Failed to connect to Redis: {}", e);
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let web_adapter = Arc::new(WebChannelAdapter::new());
|
|
|
|
|
let voice_adapter = Arc::new(VoiceAdapter::new());
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 10:34:06 -03:00
|
|
|
let drive = create_s3_operator(&config.drive)
|
2025-11-11 09:42:52 -03:00
|
|
|
.await
|
2025-12-28 21:26:08 -03:00
|
|
|
.map_err(|e| std::io::Error::other(format!("Failed to initialize Drive: {}", e)))?;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2026-01-02 18:26:34 -03:00
|
|
|
ensure_vendor_files_in_minio(&drive).await;
|
|
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let session_manager = Arc::new(tokio::sync::Mutex::new(session::SessionManager::new(
|
2025-12-28 21:26:08 -03:00
|
|
|
pool.get().map_err(|e| std::io::Error::other(format!("Failed to get database connection: {}", e)))?,
|
2025-11-11 09:42:52 -03:00
|
|
|
redis_client.clone(),
|
|
|
|
|
)));
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-22 22:54:45 -03:00
|
|
|
#[cfg(feature = "directory")]
|
2026-01-06 22:56:35 -03:00
|
|
|
let zitadel_config = {
|
|
|
|
|
// Try to load from directory_config.json first
|
|
|
|
|
let config_path = "./config/directory_config.json";
|
|
|
|
|
if let Ok(content) = std::fs::read_to_string(config_path) {
|
|
|
|
|
if let Ok(json) = serde_json::from_str::<serde_json::Value>(&content) {
|
|
|
|
|
let base_url = json.get("base_url")
|
|
|
|
|
.and_then(|v| v.as_str())
|
|
|
|
|
.unwrap_or("http://localhost:8300");
|
|
|
|
|
let client_id = json.get("client_id")
|
|
|
|
|
.and_then(|v| v.as_str())
|
|
|
|
|
.unwrap_or("");
|
|
|
|
|
let client_secret = json.get("client_secret")
|
|
|
|
|
.and_then(|v| v.as_str())
|
|
|
|
|
.unwrap_or("");
|
|
|
|
|
|
|
|
|
|
info!("Loaded Zitadel config from {}: url={}", config_path, base_url);
|
|
|
|
|
|
|
|
|
|
botserver::directory::client::ZitadelConfig {
|
|
|
|
|
issuer_url: base_url.to_string(),
|
|
|
|
|
issuer: base_url.to_string(),
|
|
|
|
|
client_id: client_id.to_string(),
|
|
|
|
|
client_secret: client_secret.to_string(),
|
|
|
|
|
redirect_uri: format!("{}/callback", base_url),
|
|
|
|
|
project_id: "default".to_string(),
|
|
|
|
|
api_url: base_url.to_string(),
|
|
|
|
|
service_account_key: None,
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
warn!("Failed to parse directory_config.json, using defaults");
|
|
|
|
|
botserver::directory::client::ZitadelConfig {
|
|
|
|
|
issuer_url: "http://localhost:8300".to_string(),
|
|
|
|
|
issuer: "http://localhost:8300".to_string(),
|
|
|
|
|
client_id: String::new(),
|
|
|
|
|
client_secret: String::new(),
|
|
|
|
|
redirect_uri: "http://localhost:8300/callback".to_string(),
|
|
|
|
|
project_id: "default".to_string(),
|
|
|
|
|
api_url: "http://localhost:8300".to_string(),
|
|
|
|
|
service_account_key: None,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
warn!("directory_config.json not found, using default Zitadel config");
|
|
|
|
|
botserver::directory::client::ZitadelConfig {
|
|
|
|
|
issuer_url: "http://localhost:8300".to_string(),
|
|
|
|
|
issuer: "http://localhost:8300".to_string(),
|
|
|
|
|
client_id: String::new(),
|
|
|
|
|
client_secret: String::new(),
|
|
|
|
|
redirect_uri: "http://localhost:8300/callback".to_string(),
|
|
|
|
|
project_id: "default".to_string(),
|
|
|
|
|
api_url: "http://localhost:8300".to_string(),
|
|
|
|
|
service_account_key: None,
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-22 12:26:16 -03:00
|
|
|
};
|
2025-11-22 22:54:45 -03:00
|
|
|
#[cfg(feature = "directory")]
|
|
|
|
|
let auth_service = Arc::new(tokio::sync::Mutex::new(
|
2026-01-06 22:56:35 -03:00
|
|
|
botserver::directory::AuthService::new(zitadel_config.clone()).map_err(|e| std::io::Error::other(format!("Failed to create auth service: {}", e)))?,
|
2025-11-22 22:54:45 -03:00
|
|
|
));
|
2026-01-06 22:56:35 -03:00
|
|
|
|
|
|
|
|
#[cfg(feature = "directory")]
|
|
|
|
|
{
|
|
|
|
|
let pat_path = std::path::Path::new("./botserver-stack/conf/directory/admin-pat.txt");
|
|
|
|
|
let bootstrap_client = if pat_path.exists() {
|
|
|
|
|
match std::fs::read_to_string(pat_path) {
|
|
|
|
|
Ok(pat_token) => {
|
|
|
|
|
let pat_token = pat_token.trim().to_string();
|
|
|
|
|
info!("Using admin PAT token for bootstrap authentication");
|
|
|
|
|
botserver::directory::client::ZitadelClient::with_pat_token(zitadel_config, pat_token)
|
|
|
|
|
.map_err(|e| std::io::Error::other(format!("Failed to create bootstrap client with PAT: {}", e)))?
|
|
|
|
|
}
|
|
|
|
|
Err(e) => {
|
|
|
|
|
warn!("Failed to read admin PAT token: {}, falling back to OAuth2", e);
|
|
|
|
|
botserver::directory::client::ZitadelClient::new(zitadel_config)
|
|
|
|
|
.map_err(|e| std::io::Error::other(format!("Failed to create bootstrap client: {}", e)))?
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
info!("Admin PAT not found, using OAuth2 client credentials for bootstrap");
|
|
|
|
|
botserver::directory::client::ZitadelClient::new(zitadel_config)
|
|
|
|
|
.map_err(|e| std::io::Error::other(format!("Failed to create bootstrap client: {}", e)))?
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
match botserver::directory::bootstrap::check_and_bootstrap_admin(&bootstrap_client).await {
|
|
|
|
|
Ok(Some(_)) => {
|
|
|
|
|
info!("Bootstrap completed - admin credentials displayed in console");
|
|
|
|
|
}
|
|
|
|
|
Ok(None) => {
|
|
|
|
|
info!("Admin user exists, bootstrap skipped");
|
|
|
|
|
}
|
|
|
|
|
Err(e) => {
|
|
|
|
|
warn!("Bootstrap check failed (Zitadel may not be ready): {}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-11 09:42:52 -03:00
|
|
|
let config_manager = ConfigManager::new(pool.clone());
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-28 21:26:08 -03:00
|
|
|
let mut bot_conn = pool.get().map_err(|e| std::io::Error::other(format!("Failed to get database connection: {}", e)))?;
|
2025-12-08 00:19:29 -03:00
|
|
|
let (default_bot_id, default_bot_name) = crate::bot::get_default_bot(&mut bot_conn);
|
|
|
|
|
info!(
|
|
|
|
|
"Using default bot: {} (id: {})",
|
|
|
|
|
default_bot_name, default_bot_id
|
|
|
|
|
);
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let llm_url = config_manager
|
2025-12-08 00:19:29 -03:00
|
|
|
.get_config(&default_bot_id, "llm-url", Some("http://localhost:8081"))
|
|
|
|
|
.unwrap_or_else(|_| "http://localhost:8081".to_string());
|
|
|
|
|
info!("LLM URL: {}", llm_url);
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-29 08:07:42 -03:00
|
|
|
let llm_model = config_manager
|
|
|
|
|
.get_config(&default_bot_id, "llm-model", Some(""))
|
|
|
|
|
.unwrap_or_default();
|
|
|
|
|
if !llm_model.is_empty() {
|
|
|
|
|
info!("LLM Model: {}", llm_model);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let _llm_key = config_manager
|
|
|
|
|
.get_config(&default_bot_id, "llm-key", Some(""))
|
|
|
|
|
.unwrap_or_default();
|
|
|
|
|
|
|
|
|
|
let base_llm_provider = botserver::llm::create_llm_provider_from_url(
|
|
|
|
|
&llm_url,
|
|
|
|
|
if llm_model.is_empty() { None } else { Some(llm_model.clone()) },
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let dynamic_llm_provider = Arc::new(botserver::llm::DynamicLLMProvider::new(base_llm_provider));
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-26 15:27:47 -03:00
|
|
|
let llm_provider: Arc<dyn botserver::llm::LLMProvider> = if let Some(ref cache) = redis_client {
|
|
|
|
|
let embedding_url = config_manager
|
|
|
|
|
.get_config(
|
|
|
|
|
&default_bot_id,
|
|
|
|
|
"embedding-url",
|
2025-12-08 00:19:29 -03:00
|
|
|
Some("http://localhost:8082"),
|
2025-11-26 15:27:47 -03:00
|
|
|
)
|
2025-12-08 00:19:29 -03:00
|
|
|
.unwrap_or_else(|_| "http://localhost:8082".to_string());
|
2025-11-26 15:27:47 -03:00
|
|
|
let embedding_model = config_manager
|
|
|
|
|
.get_config(&default_bot_id, "embedding-model", Some("all-MiniLM-L6-v2"))
|
|
|
|
|
.unwrap_or_else(|_| "all-MiniLM-L6-v2".to_string());
|
2025-12-08 00:19:29 -03:00
|
|
|
info!("Embedding URL: {}", embedding_url);
|
|
|
|
|
info!("Embedding Model: {}", embedding_model);
|
2025-11-26 15:27:47 -03:00
|
|
|
|
|
|
|
|
let embedding_service = Some(Arc::new(botserver::llm::cache::LocalEmbeddingService::new(
|
|
|
|
|
embedding_url,
|
|
|
|
|
embedding_model,
|
|
|
|
|
))
|
|
|
|
|
as Arc<dyn botserver::llm::cache::EmbeddingService>);
|
|
|
|
|
|
|
|
|
|
let cache_config = botserver::llm::cache::CacheConfig {
|
2025-12-23 18:40:58 -03:00
|
|
|
ttl: 3600,
|
2025-11-26 15:27:47 -03:00
|
|
|
semantic_matching: true,
|
2025-12-23 18:40:58 -03:00
|
|
|
similarity_threshold: 0.85,
|
2025-11-26 15:27:47 -03:00
|
|
|
max_similarity_checks: 100,
|
|
|
|
|
key_prefix: "llm_cache".to_string(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Arc::new(botserver::llm::cache::CachedLLMProvider::with_db_pool(
|
2025-12-29 08:07:42 -03:00
|
|
|
dynamic_llm_provider.clone() as Arc<dyn botserver::llm::LLMProvider>,
|
2025-11-26 15:27:47 -03:00
|
|
|
cache.clone(),
|
|
|
|
|
cache_config,
|
|
|
|
|
embedding_service,
|
|
|
|
|
pool.clone(),
|
|
|
|
|
))
|
|
|
|
|
} else {
|
2025-12-29 08:07:42 -03:00
|
|
|
dynamic_llm_provider.clone() as Arc<dyn botserver::llm::LLMProvider>
|
2025-11-26 15:27:47 -03:00
|
|
|
};
|
|
|
|
|
|
2025-11-26 22:54:22 -03:00
|
|
|
let kb_manager = Arc::new(botserver::core::kb::KnowledgeBaseManager::new("work"));
|
|
|
|
|
|
2025-11-27 08:34:24 -03:00
|
|
|
let task_engine = Arc::new(botserver::tasks::TaskEngine::new(pool.clone()));
|
|
|
|
|
|
2025-11-27 13:53:16 -03:00
|
|
|
let metrics_collector = botserver::core::shared::analytics::MetricsCollector::new();
|
|
|
|
|
|
|
|
|
|
let task_scheduler = None;
|
|
|
|
|
|
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
|
|
|
let (attendant_tx, _attendant_rx) = tokio::sync::broadcast::channel::<
|
|
|
|
|
botserver::core::shared::state::AttendantNotification,
|
|
|
|
|
>(1000);
|
|
|
|
|
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
let (task_progress_tx, _task_progress_rx) = tokio::sync::broadcast::channel::<
|
|
|
|
|
botserver::core::shared::state::TaskProgressEvent,
|
|
|
|
|
>(1000);
|
|
|
|
|
|
2026-01-04 08:48:27 -03:00
|
|
|
// Initialize BotDatabaseManager for per-bot database support
|
|
|
|
|
let database_url = crate::shared::utils::get_database_url_sync().unwrap_or_default();
|
|
|
|
|
let bot_database_manager = Arc::new(BotDatabaseManager::new(pool.clone(), &database_url));
|
|
|
|
|
|
|
|
|
|
// Sync all bot databases on startup - ensures each bot has its own database
|
|
|
|
|
info!("Syncing bot databases on startup...");
|
|
|
|
|
match bot_database_manager.sync_all_bot_databases() {
|
|
|
|
|
Ok(sync_result) => {
|
|
|
|
|
info!(
|
|
|
|
|
"Bot database sync complete: {} created, {} verified, {} errors",
|
|
|
|
|
sync_result.databases_created,
|
|
|
|
|
sync_result.databases_verified,
|
|
|
|
|
sync_result.errors.len()
|
|
|
|
|
);
|
|
|
|
|
for err in &sync_result.errors {
|
|
|
|
|
warn!("Bot database sync error: {}", err);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Err(e) => {
|
|
|
|
|
error!("Failed to sync bot databases: {}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let app_state = Arc::new(AppState {
|
2025-11-27 13:53:16 -03:00
|
|
|
drive: Some(drive.clone()),
|
|
|
|
|
s3_client: Some(drive),
|
2025-11-11 09:42:52 -03:00
|
|
|
config: Some(cfg.clone()),
|
|
|
|
|
conn: pool.clone(),
|
2026-01-04 08:48:27 -03:00
|
|
|
database_url: database_url.clone(),
|
|
|
|
|
bot_database_manager: bot_database_manager.clone(),
|
2025-11-11 09:42:52 -03:00
|
|
|
bucket_name: "default.gbai".to_string(),
|
|
|
|
|
cache: redis_client.clone(),
|
|
|
|
|
session_manager: session_manager.clone(),
|
2025-11-27 13:53:16 -03:00
|
|
|
metrics_collector,
|
|
|
|
|
task_scheduler,
|
2025-11-11 09:42:52 -03:00
|
|
|
llm_provider: llm_provider.clone(),
|
2025-11-22 22:54:45 -03:00
|
|
|
#[cfg(feature = "directory")]
|
2025-11-11 09:42:52 -03:00
|
|
|
auth_service: auth_service.clone(),
|
|
|
|
|
channels: Arc::new(tokio::sync::Mutex::new({
|
|
|
|
|
let mut map = HashMap::new();
|
|
|
|
|
map.insert(
|
|
|
|
|
"web".to_string(),
|
2025-11-22 22:54:45 -03:00
|
|
|
web_adapter.clone() as Arc<dyn botserver::core::bot::channels::ChannelAdapter>,
|
2025-11-11 09:42:52 -03:00
|
|
|
);
|
|
|
|
|
map
|
|
|
|
|
})),
|
|
|
|
|
response_channels: Arc::new(tokio::sync::Mutex::new(HashMap::new())),
|
|
|
|
|
web_adapter: web_adapter.clone(),
|
|
|
|
|
voice_adapter: voice_adapter.clone(),
|
2025-11-26 22:54:22 -03:00
|
|
|
kb_manager: Some(kb_manager.clone()),
|
2025-12-26 08:59:25 -03:00
|
|
|
task_engine,
|
2025-12-29 08:07:42 -03:00
|
|
|
extensions: {
|
|
|
|
|
let ext = botserver::core::shared::state::Extensions::new();
|
|
|
|
|
ext.insert_blocking(Arc::clone(&dynamic_llm_provider));
|
|
|
|
|
ext
|
|
|
|
|
},
|
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
|
|
|
attendant_broadcast: Some(attendant_tx),
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
task_progress_broadcast: Some(task_progress_tx),
|
2026-01-13 22:21:25 -03:00
|
|
|
billing_alert_broadcast: None,
|
2025-12-31 23:45:29 -03:00
|
|
|
task_manifests: Arc::new(std::sync::RwLock::new(HashMap::new())),
|
Add video module, RBAC, security features, billing, contacts, dashboards, learn, social, and multiple new modules
Major additions:
- Video editing engine with AI features (transcription, captions, TTS, scene detection)
- RBAC middleware and organization management
- Security enhancements (MFA, passkey, DLP, encryption, audit)
- Billing and subscription management
- Contacts management
- Dashboards module
- Learn/LMS module
- Social features
- Compliance (SOC2, SOP middleware, vulnerability scanner)
- New migrations for RBAC, learn, and video tables
2026-01-08 13:16:17 -03:00
|
|
|
project_service: Arc::new(tokio::sync::RwLock::new(botserver::project::ProjectService::new())),
|
|
|
|
|
legal_service: Arc::new(tokio::sync::RwLock::new(botserver::legal::LegalService::new())),
|
2026-01-10 09:41:12 -03:00
|
|
|
jwt_manager: None,
|
|
|
|
|
auth_provider_registry: None,
|
|
|
|
|
rbac_manager: None,
|
2025-11-11 09:42:52 -03:00
|
|
|
});
|
2025-11-27 13:53:16 -03:00
|
|
|
|
|
|
|
|
let task_scheduler = Arc::new(botserver::tasks::scheduler::TaskScheduler::new(
|
|
|
|
|
app_state.clone(),
|
|
|
|
|
));
|
|
|
|
|
|
2025-12-26 08:59:25 -03:00
|
|
|
task_scheduler.start();
|
2025-12-23 18:40:58 -03:00
|
|
|
|
2025-11-26 22:54:22 -03:00
|
|
|
if let Err(e) = botserver::core::kb::ensure_crawler_service_running(app_state.clone()).await {
|
|
|
|
|
log::warn!("Failed to start website crawler service: {}", e);
|
|
|
|
|
}
|
|
|
|
|
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
// Start memory monitoring - check every 30 seconds, warn if growth > 50MB
|
|
|
|
|
start_memory_monitor(30, 50);
|
|
|
|
|
info!("Memory monitor started");
|
|
|
|
|
log_process_memory();
|
|
|
|
|
|
feat(autotask): Implement AutoTask system with intent classification and app generation
- Add IntentClassifier with 7 intent types (APP_CREATE, TODO, MONITOR, ACTION, SCHEDULE, GOAL, TOOL)
- Add AppGenerator with LLM-powered app structure analysis
- Add DesignerAI for modifying apps through conversation
- Add app_server for serving generated apps with clean URLs
- Add db_api for CRUD operations on bot database tables
- Add ask_later keyword for pending info collection
- Add migration 6.1.1 with tables: pending_info, auto_tasks, execution_plans, task_approvals, task_decisions, safety_audit_log, generated_apps, intent_classifications, designer_changes
- Write apps to S3 drive and sync to SITE_ROOT for serving
- Clean URL structure: /apps/{app_name}/
- Integrate with DriveMonitor for file sync
Based on Chapter 17 - Autonomous Tasks specification
2025-12-27 21:10:09 -03:00
|
|
|
let _ = state_tx.try_send(app_state.clone());
|
2025-11-11 09:42:52 -03:00
|
|
|
progress_tx.send(BootstrapProgress::BootstrapComplete).ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
info!(
|
|
|
|
|
"Starting HTTP server on {}:{}",
|
|
|
|
|
config.server.host, config.server.port
|
|
|
|
|
);
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let worker_count = std::thread::available_parallelism()
|
|
|
|
|
.map(|n| n.get())
|
|
|
|
|
.unwrap_or(4);
|
2025-11-15 09:48:46 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let bot_orchestrator = BotOrchestrator::new(app_state.clone());
|
feat(autotask): Implement AutoTask system with intent classification and app generation
- Add IntentClassifier with 7 intent types (APP_CREATE, TODO, MONITOR, ACTION, SCHEDULE, GOAL, TOOL)
- Add AppGenerator with LLM-powered app structure analysis
- Add DesignerAI for modifying apps through conversation
- Add app_server for serving generated apps with clean URLs
- Add db_api for CRUD operations on bot database tables
- Add ask_later keyword for pending info collection
- Add migration 6.1.1 with tables: pending_info, auto_tasks, execution_plans, task_approvals, task_decisions, safety_audit_log, generated_apps, intent_classifications, designer_changes
- Write apps to S3 drive and sync to SITE_ROOT for serving
- Clean URL structure: /apps/{app_name}/
- Integrate with DriveMonitor for file sync
Based on Chapter 17 - Autonomous Tasks specification
2025-12-27 21:10:09 -03:00
|
|
|
if let Err(e) = bot_orchestrator.mount_all_bots() {
|
|
|
|
|
error!("Failed to mount bots: {}", e);
|
|
|
|
|
}
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-29 08:07:42 -03:00
|
|
|
#[cfg(feature = "drive")]
|
|
|
|
|
{
|
|
|
|
|
let drive_monitor_state = app_state.clone();
|
|
|
|
|
let bucket_name = "default.gbai".to_string();
|
|
|
|
|
let monitor_bot_id = default_bot_id;
|
|
|
|
|
tokio::spawn(async move {
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
register_thread("drive-monitor", "drive");
|
2026-01-06 22:56:35 -03:00
|
|
|
trace!("DriveMonitor::new starting...");
|
2025-12-29 08:07:42 -03:00
|
|
|
let monitor = botserver::DriveMonitor::new(
|
|
|
|
|
drive_monitor_state,
|
|
|
|
|
bucket_name.clone(),
|
|
|
|
|
monitor_bot_id,
|
|
|
|
|
);
|
2026-01-06 22:56:35 -03:00
|
|
|
trace!("DriveMonitor::new done, calling start_monitoring...");
|
2025-12-29 08:07:42 -03:00
|
|
|
info!("Starting DriveMonitor for bucket: {}", bucket_name);
|
|
|
|
|
if let Err(e) = monitor.start_monitoring().await {
|
|
|
|
|
error!("DriveMonitor failed: {}", e);
|
|
|
|
|
}
|
2026-01-06 22:56:35 -03:00
|
|
|
trace!("DriveMonitor start_monitoring returned");
|
2025-12-29 08:07:42 -03:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let automation_state = app_state.clone();
|
2025-11-19 14:00:57 -03:00
|
|
|
tokio::spawn(async move {
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
register_thread("automation-service", "automation");
|
2025-11-19 14:00:57 -03:00
|
|
|
let automation = AutomationService::new(automation_state);
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
trace!("[TASK] AutomationService starting, RSS={}",
|
|
|
|
|
MemoryStats::format_bytes(MemoryStats::current().rss_bytes));
|
|
|
|
|
loop {
|
|
|
|
|
record_thread_activity("automation-service");
|
|
|
|
|
if let Err(e) = automation.check_scheduled_tasks().await {
|
|
|
|
|
error!("Error checking scheduled tasks: {}", e);
|
|
|
|
|
}
|
|
|
|
|
tokio::time::sleep(tokio::time::Duration::from_secs(60)).await;
|
|
|
|
|
}
|
2025-11-11 09:42:52 -03:00
|
|
|
});
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let app_state_for_llm = app_state.clone();
|
|
|
|
|
tokio::spawn(async move {
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
register_thread("llm-server-init", "llm");
|
2026-01-06 22:56:35 -03:00
|
|
|
trace!("ensure_llama_servers_running starting...");
|
2025-11-11 09:42:52 -03:00
|
|
|
if let Err(e) = ensure_llama_servers_running(app_state_for_llm).await {
|
|
|
|
|
error!("Failed to start LLM servers: {}", e);
|
|
|
|
|
}
|
2026-01-06 22:56:35 -03:00
|
|
|
trace!("ensure_llama_servers_running completed");
|
Fix tasks UI, WebSocket progress, memory monitoring, and app generator
Tasks UI fixes:
- Fix task list to query auto_tasks table instead of tasks table
- Fix task detail endpoint to use UUID binding for auto_tasks query
- Add proper filter handling: complete, active, awaiting, paused, blocked
- Add TaskStats fields: awaiting, paused, blocked, time_saved
- Add /api/tasks/time-saved endpoint
- Add count-all to stats HTML response
App generator improvements:
- Add AgentActivity struct for detailed terminal-style progress
- Add emit_activity method for rich progress events
- Add detailed logging for LLM calls with timing
- Track files_written, tables_synced, bytes_generated
Memory and performance:
- Add memory_monitor module for tracking RSS and thread activity
- Skip 0-byte files in drive monitor and document processor
- Change DRIVE_MONITOR checking logs from info to trace
- Remove unused profile_section macro
WebSocket progress:
- Ensure TaskProgressEvent includes activity field
- Add with_activity builder method
2025-12-30 22:42:32 -03:00
|
|
|
record_thread_activity("llm-server-init");
|
2025-11-11 09:42:52 -03:00
|
|
|
});
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Initial data setup task spawned");
|
MS Office 100% Compatibility - Phase 1 Implementation
- Add rust_xlsxwriter for Excel export with formatting support
- Add docx-rs for Word document import/export with HTML conversion
- Add PPTX export support with slides, shapes, and text elements
- Refactor sheet module into 7 files (types, formulas, handlers, etc)
- Refactor docs module into 6 files (types, handlers, storage, etc)
- Refactor slides module into 6 files (types, handlers, storage, etc)
- Fix collaboration modules (borrow issues, rand compatibility)
- Add ooxmlsdk dependency for future Office 2021 features
- Fix type mismatches in slides storage
- Update security protection API router type
Features:
- Excel: Read xlsx/xlsm/xls, write xlsx with styles
- Word: Read/write docx with formatting preservation
- PowerPoint: Write pptx with slides, shapes, text
- Real-time collaboration via WebSocket (already working)
- Theme-aware UI with --sentient-* CSS variables
2026-01-11 09:56:15 -03:00
|
|
|
trace!("All system threads started, starting HTTP server...");
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2026-01-06 22:56:35 -03:00
|
|
|
info!("Starting HTTP server on port {}...", config.server.port);
|
2025-12-29 08:45:46 -03:00
|
|
|
if let Err(e) = run_axum_server(app_state, config.server.port, worker_count).await {
|
|
|
|
|
error!("Failed to start HTTP server: {}", e);
|
2025-12-29 10:28:49 -03:00
|
|
|
std::process::exit(1);
|
2025-12-29 08:45:46 -03:00
|
|
|
}
|
2026-01-06 22:56:35 -03:00
|
|
|
trace!("run_axum_server returned (should not happen normally)");
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-02 21:09:43 -03:00
|
|
|
if let Some(handle) = ui_handle {
|
|
|
|
|
handle.join().ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
}
|
|
|
|
|
|
2025-11-15 09:48:46 -03:00
|
|
|
Ok(())
|
2025-10-06 10:30:17 -03:00
|
|
|
}
|