use actix_web::{get, web, App, HttpResponse, HttpServer, Responder}; use serde_json::json; use sqlx::PgPool; use std::env; pub mod auth; mod models; mod routes; pub struct Config { pub jwt_secret: String, pub is_production: bool, } #[get("/")] async fn index() -> impl Responder { "Welcome to the Torus API" } #[actix_web::main] async fn main() -> std::io::Result<()> { dotenvy::dotenv().ok(); let app_env = env::var("APP_ENV").unwrap_or_else(|_| "development".to_string()); let port: u16 = env::var("PORT") .unwrap_or_else(|_| "8080".to_string()) .parse() .expect("PORT must be a valid number"); let host = if app_env == "production" { "example.com".to_string() } else { "127.0.0.1".to_string() }; let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); let pool = PgPool::connect(&database_url) .await .expect("Failed to connect to Postgres"); let config = web::Data::new(Config { jwt_secret: env::var("JWT_SECRET").expect("JWT_SECRET must be set"), is_production: app_env == "production", }); println!("Starting server on {}:{} ({})", host, port, app_env); HttpServer::new(move || { let json_cfg = web::JsonConfig::default().error_handler(|_err, _req| { let response = HttpResponse::BadRequest() .json(json!({"error": "Invalid request body. Please check your data and try again."})); actix_web::error::InternalError::from_response(_err, response).into() }); App::new() .app_data(web::Data::new(pool.clone())) .app_data(config.clone()) .app_data(json_cfg) .service(index) .service(routes::users::create::create_user) .service(routes::users::login::login) .service(routes::users::logout::logout) .service(routes::users::get::get_user) .service(routes::workouts::create::create_workout) .service(routes::workouts::delete::delete_workout) .service(routes::workouts::get::get_workout) .service(routes::workouts::list::list_workouts) .service(routes::workouts::update::update_workout) }) .bind((host.as_str(), port))? .run() .await }