this repo has no description
1mod auth;
2mod config;
3mod db;
4mod errors;
5mod models;
6mod routes;
7
8use axum::routing::{get, post, put};
9use axum::Router;
10use tower_http::cors::{Any, CorsLayer};
11use tower_http::services::{ServeDir, ServeFile};
12
13#[tokio::main]
14async fn main() {
15 // Load .env file (silently ignore if missing).
16 let _ = dotenvy::dotenv();
17
18 let database_url = config::database_url();
19 let pool = db::init_pool(&database_url).await;
20 db::run_migrations(&pool).await;
21
22 let state = config::AppState::from_env(pool);
23 let port = config::port();
24
25 let cors = CorsLayer::new()
26 .allow_origin(Any)
27 .allow_methods([
28 axum::http::Method::GET,
29 axum::http::Method::POST,
30 axum::http::Method::PUT,
31 axum::http::Method::DELETE,
32 ])
33 .allow_headers([
34 axum::http::header::AUTHORIZATION,
35 axum::http::header::CONTENT_TYPE,
36 ]);
37
38 let mut app = Router::new()
39 .route("/api/register", post(routes::auth::register))
40 .route("/api/login", post(routes::auth::login))
41 .route("/api/me", get(routes::auth::me))
42 .route(
43 "/api/progress",
44 get(routes::progress::get_progress).put(routes::progress::update_progress),
45 )
46 .route(
47 "/api/lesson-state",
48 put(routes::lesson_state::save_lesson_state),
49 )
50 .route(
51 "/api/lesson-state/{topic_id}/{lesson_id}",
52 get(routes::lesson_state::get_lesson_state)
53 .delete(routes::lesson_state::delete_lesson_state),
54 )
55 .route("/api/tts", get(routes::tts::synthesize))
56 .layer(cors)
57 .with_state(state);
58
59 // In production, serve the frontend build as static files with SPA fallback
60 if let Some(static_dir) = config::static_dir() {
61 let index = format!("{}/index.html", static_dir);
62 app = app.fallback_service(ServeDir::new(&static_dir).fallback(ServeFile::new(index)));
63 println!("Serving static files from {static_dir}");
64 }
65
66 let addr = format!("0.0.0.0:{port}");
67 let listener = tokio::net::TcpListener::bind(&addr)
68 .await
69 .expect("Failed to bind");
70
71 println!("Ayos API listening on http://{addr}");
72
73 axum::serve(listener, app).await.expect("Server error");
74}