/// Cookie and JWT authentication utilities mod cookie; /// Environment configuration loading mod env; /// HTTP request handlers for all endpoints mod handlers; /// Data structures for request/response serialization mod models; /// Axum router configuration with all routes and middleware mod router; use std::sync::Arc; use axum::http::{ HeaderValue, Method, header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE}, }; use dotenv::dotenv; use router::create_router; use sqlx::{PgPool, postgres::PgPoolOptions}; use tower_http::cors::CorsLayer; use crate::env::Env; /// Shared application state passed to all route handlers. /// /// Contains the database connection pool and environment configuration. /// This is wrapped in Arc for thread-safe sharing across async tasks. /// /// # Fields /// - `db`: PostgreSQL connection pool for database access /// - `env`: Configuration loaded from environment variables pub struct AppState { db: PgPool, env: Env, } /// Main application entry point. /// /// Initializes the server by: /// 1. Loading environment variables from `.env` file /// 2. Establishing database connection pool /// 3. Configuring CORS policy for cross-origin requests /// 4. Starting HTTP server on port 8001 /// /// # Server Configuration /// - Binds to `0.0.0.0:8001` (all network interfaces) /// - Allows: GET, POST, PATCH, DELETE methods /// - Allows credentials and custom headers /// - CORS origin configured from environment /// /// # Panics /// - If environment loading fails /// - If database connection fails #[tokio::main] async fn main() { dotenv().ok(); let env = Env::load(); let database_url = &env.db_url; // Establish connection pool to PostgreSQL let pool = match PgPoolOptions::new().connect(&database_url).await { Ok(pool) => { println!("Database connection successful"); pool } Err(err) => { println!("Failed to connect to database: {:?}", err); std::process::exit(1); } }; // Configure CORS to allow requests from frontend let cors = CorsLayer::new() .allow_origin(env.origin.parse::().unwrap()) .allow_methods([Method::GET, Method::POST, Method::PATCH, Method::DELETE]) .allow_credentials(true) .allow_headers([AUTHORIZATION, ACCEPT, CONTENT_TYPE]); // Build router with all endpoints and apply CORS middleware let app = create_router(Arc::new(AppState { db: pool.clone(), env: env.clone(), })) .layer(cors); // Start listening for incoming connections let listener = tokio::net::TcpListener::bind("0.0.0.0:8001").await.unwrap(); let _ = axum::serve(listener, app).await; }