mod db; mod routes; use axum::{routing::get, Router}; use sqlx::sqlite::SqlitePoolOptions; use std::env; use tower_http::services::{ServeDir, ServeFile}; #[tokio::main] async fn main() { let db_url = env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite:colony.db?mode=rwc".into()); let port = env::var("PORT").unwrap_or_else(|_| "3001".into()); let pool = SqlitePoolOptions::new() .max_connections(5) .connect(&db_url) .await .expect("Failed to connect to database"); // Enable WAL mode sqlx::query("PRAGMA journal_mode=WAL") .execute(&pool) .await .unwrap(); // Run migrations using sqlx's proper migration system sqlx::migrate!("./migrations") .run(&pool) .await .expect("Failed to run migrations"); println!("Colony running on port {}", port); let app = Router::new() .route("/api/health", get(routes::health)) .route("/api/users", get(routes::list_users)) .route("/api/me", get(routes::get_me)) .route( "/api/channels", get(routes::list_channels).post(routes::create_channel), ) .route("/api/channels/{id}", get(routes::get_channel)) .route( "/api/channels/{channel_id}/messages", get(routes::list_messages).post(routes::post_message), ) // Serve frontend static files, fallback to index.html for SPA routing .fallback_service( ServeDir::new("static").fallback(ServeFile::new("static/index.html")), ) .with_state(pool); let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port)) .await .unwrap(); axum::serve(listener, app).await.unwrap(); }