mockforge_collab/
server.rs1use crate::api::{create_router as create_api_router, ApiState};
4use crate::auth::AuthService;
5use crate::config::CollabConfig;
6use crate::error::Result;
7use crate::events::EventBus;
8use crate::history::{History, VersionControl};
9use crate::sync::SyncEngine;
10use crate::user::UserService;
11use crate::websocket::{ws_handler, WsState};
12use crate::workspace::WorkspaceService;
13use axum::routing::get;
14use axum::Router;
15use sqlx::{Pool, Sqlite};
16use std::sync::Arc;
17
18pub struct CollabServer {
20 config: CollabConfig,
22 db: Pool<Sqlite>,
24 auth: Arc<AuthService>,
26 user: Arc<UserService>,
28 workspace: Arc<WorkspaceService>,
30 event_bus: Arc<EventBus>,
32 sync: Arc<SyncEngine>,
34 history: Arc<History>,
36}
37
38impl CollabServer {
39 pub async fn new(config: CollabConfig) -> Result<Self> {
41 let db = sqlx::SqlitePool::connect(&config.database_url).await?;
43
44 sqlx::migrate!("./migrations").run(&db).await?;
46
47 let auth = Arc::new(AuthService::new(config.jwt_secret.clone()));
49 let user = Arc::new(UserService::new(db.clone(), auth.clone()));
50 let workspace = Arc::new(WorkspaceService::new(db.clone()));
51 let event_bus = Arc::new(EventBus::new(config.event_bus_capacity));
52 let sync = Arc::new(SyncEngine::new(event_bus.clone()));
53 let mut history = History::new(db.clone());
54 history.set_auto_commit(config.auto_commit);
55 let history = Arc::new(history);
56
57 Ok(Self {
58 config,
59 db,
60 auth,
61 user,
62 workspace,
63 event_bus,
64 sync,
65 history,
66 })
67 }
68
69 pub async fn run(self, addr: &str) -> Result<()> {
71 tracing::info!("Starting MockForge Collaboration Server on {}", addr);
72
73 let version_control = Arc::new(VersionControl::new(self.db.clone()));
75 let api_state = ApiState {
76 auth: self.auth.clone(),
77 user: self.user.clone(),
78 workspace: self.workspace.clone(),
79 history: version_control,
80 };
81 let api_router = create_api_router(api_state);
82
83 let ws_state = WsState {
85 auth: self.auth.clone(),
86 sync: self.sync.clone(),
87 event_bus: self.event_bus.clone(),
88 };
89
90 let app = Router::new()
92 .route("/ws", get(ws_handler))
93 .with_state(ws_state)
94 .merge(api_router);
95
96 let listener = tokio::net::TcpListener::bind(addr)
98 .await
99 .map_err(|e| crate::error::CollabError::Internal(format!("Failed to bind: {}", e)))?;
100
101 tracing::info!("Server listening on {}", addr);
102
103 axum::serve(listener, app)
105 .await
106 .map_err(|e| crate::error::CollabError::Internal(format!("Server error: {}", e)))?;
107
108 Ok(())
109 }
110
111 pub fn auth(&self) -> Arc<AuthService> {
113 self.auth.clone()
114 }
115
116 pub fn workspace(&self) -> Arc<WorkspaceService> {
118 self.workspace.clone()
119 }
120
121 pub fn sync(&self) -> Arc<SyncEngine> {
123 self.sync.clone()
124 }
125
126 pub fn history(&self) -> Arc<History> {
128 self.history.clone()
129 }
130}