diff --git a/src/backend/Cargo.toml b/src/backend/Cargo.toml index a8530db..0a335df 100644 --- a/src/backend/Cargo.toml +++ b/src/backend/Cargo.toml @@ -14,6 +14,7 @@ rand_core = { version = "0.6", features = ["getrandom"] } regex = "1.12.2" serde = { version = "1.0.228", features = ["derive", "serde_derive"] } serde_json = "1.0.145" +sqlx = { version = "0.8.6", features = ["runtime-tokio-rustls", "postgres", "uuid", "chrono", "migrate"] } tokio = { version = "1.48.0", features = ["macros", "rt-multi-thread"] } tower = { version = "0.5.2", features = ["tokio", "tracing"] } tower-http = { version = "0.6.7", features = ["cors"] } diff --git a/src/backend/migrations/0001_init.sql b/src/backend/migrations/0001_init.sql new file mode 100644 index 0000000..ac6280f --- /dev/null +++ b/src/backend/migrations/0001_init.sql @@ -0,0 +1,7 @@ +CREATE TABLE system_state ( + id INTEGER PRIMARY KEY CHECK (id = 1), + initialized BOOLEAN NOT NULL DEFAULT false +); + +INSERT INTO system_state (id, initialized) VALUES (1, true) +ON CONFLICT (id) DO NOTHING; diff --git a/src/backend/src/core/user_routines.rs b/src/backend/src/core/user_routines.rs index ee819d5..4d98f09 100644 --- a/src/backend/src/core/user_routines.rs +++ b/src/backend/src/core/user_routines.rs @@ -1,5 +1,23 @@ +use crate::prelude::*; use std::sync::Arc; -use crate::{domain::user::NewUser, state::AppState}; +use axum::http::StatusCode; +use validator::Validate; -pub async fn create(state: Arc, new_user: NewUser) -> Result {} +use crate::{ + domain::user::{InternalNewUser, NewUser, User}, + state::AppState, +}; + +pub async fn create(state: Arc, new_user: NewUser) -> Result { + if let Err(_) = new_user.validate() { + return Err(StatusCode::BAD_REQUEST); + } + + let internal = InternalNewUser::try_from(new_user).map_err(|e| { + error!("Conversion to InternalUser failed: {e}"); + StatusCode::INTERNAL_SERVER_ERROR + })?; + + todo!("Hook up return once db setup ready"); +} diff --git a/src/backend/src/infra/db/mod.rs b/src/backend/src/infra/db/mod.rs new file mode 100644 index 0000000..5505eef --- /dev/null +++ b/src/backend/src/infra/db/mod.rs @@ -0,0 +1,20 @@ +use std::time::Duration; + +use sqlx::{PgPool, postgres::PgPoolOptions}; + +use anyhow::Result; + +pub async fn connect(database_url: &str) -> Result { + let pool = PgPoolOptions::new() + .max_connections(10) + .acquire_timeout(Duration::from_secs(5)) + .connect(database_url) + .await?; + + Ok(pool) +} + +pub async fn migrate(pool: &PgPool) -> Result<()> { + sqlx::migrate!().run(&pool).await?; + Ok(()) +} diff --git a/src/backend/src/infra/mod.rs b/src/backend/src/infra/mod.rs new file mode 100644 index 0000000..dec1023 --- /dev/null +++ b/src/backend/src/infra/mod.rs @@ -0,0 +1 @@ +pub mod db; diff --git a/src/backend/src/lib.rs b/src/backend/src/lib.rs index 733250c..ed7e20b 100644 --- a/src/backend/src/lib.rs +++ b/src/backend/src/lib.rs @@ -1,5 +1,7 @@ pub mod auth; pub mod core; pub mod domain; +pub mod infra; +pub mod prelude; pub mod router; pub mod state; diff --git a/src/backend/src/prelude.rs b/src/backend/src/prelude.rs new file mode 100644 index 0000000..c55b5c2 --- /dev/null +++ b/src/backend/src/prelude.rs @@ -0,0 +1 @@ +pub use tracing::{debug, error, info, warn}; diff --git a/src/backend/src/router/user_routes.rs b/src/backend/src/router/user_routes.rs index 62f17c1..66175ad 100644 --- a/src/backend/src/router/user_routes.rs +++ b/src/backend/src/router/user_routes.rs @@ -23,7 +23,5 @@ pub async fn create( StatusCode::INTERNAL_SERVER_ERROR })?; - let user = User::from(internal); - - Ok(Json(user)) + todo!("Hook up return once db setup ready"); }