diff --git a/backend/Makefile b/backend/Makefile index db946f7..f5f741d 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -19,5 +19,5 @@ aws-logs-app: seed: docker compose run --rm backend cargo run --bin seed -test: - cargo test -- --nocapture && make seed +test: seed + cargo test -- --nocapture --test-threads=1 diff --git a/backend/src/controllers/user/point_conditions.rs b/backend/src/controllers/user/point_conditions.rs index d184ed0..101f8d9 100644 --- a/backend/src/controllers/user/point_conditions.rs +++ b/backend/src/controllers/user/point_conditions.rs @@ -8,14 +8,10 @@ use sqlx::PgPool; use crate::{ midleware::{auth, error}, models::point_condition, + services::open_meteo, + requests, }; -#[derive(serde::Deserialize)] -pub struct NewRequest { - lat: f64, - lon: f64, -} - pub async fn index( State(pool): State, claims: auth::Claims, @@ -31,8 +27,19 @@ pub async fn index( pub async fn create( State(pool): State, claims: auth::Claims, - Json(payload): Json, + Json(payload): Json, ) -> Result, error::AppError> { + + let res = open_meteo::get_marine_weather( + payload.lat, + payload.lon, + &payload.start_date, + &payload.end_date, + &payload.timezone, + ).await; + + println!("{:#?}", res); + let current_user = claims.get_current_user(&pool).await?; let new = point_condition::New { user_id: current_user.id, @@ -40,5 +47,6 @@ pub async fn create( lon: payload.lon, }; let created = point_condition::create(&pool, new).await?; + Ok(Json(created)) } diff --git a/backend/src/controllers/user/registration.rs b/backend/src/controllers/user/registration.rs index 0ea8a09..b4ef6f4 100644 --- a/backend/src/controllers/user/registration.rs +++ b/backend/src/controllers/user/registration.rs @@ -8,17 +8,12 @@ use sqlx::PgPool; use crate::{ midleware::error, models::user, + requests, }; -#[derive(serde::Deserialize)] -pub struct NewRequest { - email: String, - password: String, -} - pub async fn create( State(pool): State, - Json(payload): Json, + Json(payload): Json, ) -> Result, error::AppError> { let new_user = user::New { email: payload.email, diff --git a/backend/src/lib.rs b/backend/src/lib.rs index 6e56e39..a0b42e6 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -1,2 +1,5 @@ pub mod midleware; +pub mod services; +pub mod controllers; pub mod models; +pub mod requests; diff --git a/backend/src/main.rs b/backend/src/main.rs index f3010cd..78f7d8c 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -5,6 +5,8 @@ mod routes; mod midleware; mod controllers; mod models; +mod services; +mod requests; #[tokio::main] async fn main() { diff --git a/backend/src/midleware/auth.rs b/backend/src/midleware/auth.rs index 0ff28c6..d800300 100644 --- a/backend/src/midleware/auth.rs +++ b/backend/src/midleware/auth.rs @@ -25,7 +25,7 @@ use jsonwebtoken::{ Validation, }; -use sqlx::{ PgPool, FromRow }; +use sqlx::{PgPool, FromRow}; use tracing::error; use serde::{Serialize, Deserialize}; diff --git a/backend/src/midleware/db.rs b/backend/src/midleware/db.rs index c530acb..fdffef8 100644 --- a/backend/src/midleware/db.rs +++ b/backend/src/midleware/db.rs @@ -9,7 +9,7 @@ pub async fn get_db_pool() -> PgPool { .expect("not found database url."); PgPoolOptions::new() - .max_connections(5) + .max_connections(10) .acquire_timeout(Duration::from_secs(3)) .connect(&db_connection_str) .await diff --git a/backend/src/midleware/error.rs b/backend/src/midleware/error.rs index 2b75a90..ab6cb09 100644 --- a/backend/src/midleware/error.rs +++ b/backend/src/midleware/error.rs @@ -1,3 +1,5 @@ +use reqwest; + use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; use axum::Json; @@ -21,6 +23,12 @@ pub enum AppError { InternalServerError(String), } +impl From for AppError { + fn from(err: reqwest::Error) -> Self { + AppError::InternalServerError(err.to_string()) + } +} + impl From for AppError { fn from(error: sqlx::Error) -> Self { match error { diff --git a/backend/src/models/point_condition.rs b/backend/src/models/point_condition.rs index 8907263..c634c18 100644 --- a/backend/src/models/point_condition.rs +++ b/backend/src/models/point_condition.rs @@ -34,7 +34,7 @@ pub struct Entry { pub async fn create( pool: &PgPool, - new_env: New + new_condition: New ) -> Result { let sql = r#" INSERT INTO point_conditions ( @@ -47,10 +47,10 @@ pub async fn create( RETURNING id, user_id, lat, lon "#; - let created_env = query_as::<_, Created>(sql) - .bind(new_env.user_id) - .bind(new_env.lat) - .bind(new_env.lon) + let created = query_as::<_, Created>(sql) + .bind(new_condition.user_id) + .bind(new_condition.lat) + .bind(new_condition.lon) .fetch_one(pool) .await .map_err(|e| { @@ -58,7 +58,7 @@ pub async fn create( error::AppError::DatabaseError(e.to_string()) })?; - Ok(created_env) + Ok(created) } pub async fn find_by_user_id( diff --git a/backend/src/requests/mod.rs b/backend/src/requests/mod.rs new file mode 100644 index 0000000..b95c045 --- /dev/null +++ b/backend/src/requests/mod.rs @@ -0,0 +1,2 @@ +pub mod user; +pub mod point_condition; diff --git a/backend/src/requests/point_condition.rs b/backend/src/requests/point_condition.rs new file mode 100644 index 0000000..415465d --- /dev/null +++ b/backend/src/requests/point_condition.rs @@ -0,0 +1,10 @@ +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize)] +pub struct New { + pub lat: f64, + pub lon: f64, + pub start_date: String, + pub end_date: String, + pub timezone: String, +} diff --git a/backend/src/requests/user.rs b/backend/src/requests/user.rs new file mode 100644 index 0000000..3c35a10 --- /dev/null +++ b/backend/src/requests/user.rs @@ -0,0 +1,7 @@ +use serde::Deserialize; + +#[derive(Deserialize)] +pub struct NewRegistration { + pub email: String, + pub password: String, +} diff --git a/backend/src/services/mod.rs b/backend/src/services/mod.rs new file mode 100644 index 0000000..773476b --- /dev/null +++ b/backend/src/services/mod.rs @@ -0,0 +1 @@ +pub mod open_meteo; diff --git a/backend/src/services/open_meteo.rs b/backend/src/services/open_meteo.rs new file mode 100644 index 0000000..d5c76f0 --- /dev/null +++ b/backend/src/services/open_meteo.rs @@ -0,0 +1,50 @@ +use reqwest::Client; +use serde::Deserialize; + +use crate::midleware::error; + +#[derive(Debug, Deserialize)] +pub struct HourlyUnits { + pub time: String, + pub swell_wave_height: String, + pub swell_wave_direction: String, +} + +#[derive(Debug, Deserialize)] +pub struct WeatherResponse { + pub latitude: f64, + pub longitude: f64, + pub generationtime_ms: f64, + pub timezone: String, + pub timezone_abbreviation: String, + pub hourly_units: HourlyUnits, +} + +pub async fn get_marine_weather( + lat: f64, + lon: f64, + start_date: &str, + end_date: &str, + timezone: &str +) -> Result { + let client = Client::new(); + + let url = format!( + "https://marine-api.open-meteo.com/v1/marine?latitude={}&longitude={}&hourly=swell_wave_height,swell_wave_direction&timezone={}&start_date={}&end_date={}", + lat, + lon, + timezone, + start_date, + end_date, + ); + + let res = client + .get(&url) + .send() + .await? + .json::() + .await?; + + Ok(res) +} + diff --git a/backend/tests/e2e/user.rs b/backend/tests/e2e/user.rs index a832b99..83d1926 100644 --- a/backend/tests/e2e/user.rs +++ b/backend/tests/e2e/user.rs @@ -1,8 +1,9 @@ -use pointbreak::models; use reqwest::Client; use reqwest::Response; use tokio; +use pointbreak::requests; + use crate::common; const AUTH_URL: &str = "http://localhost:3000/user/session"; @@ -58,15 +59,17 @@ async fn point_conditions() { let client = Client::new(); let jwt = common::get_jwt(&client, AUTH_URL, EMAIL, PASSWORD).await; - let new_condition = models::point_condition::New { - user_id: 1, + let new_condition_req = requests::point_condition::New { lat: 0.0, lon: 0.0, + start_date: "2024-07-20".to_string(), + end_date: "2024-07-20".to_string(), + timezone: "Asia/Tokyo".to_string(), }; let res = client .post(url) - .json(&new_condition) + .json(&new_condition_req) .header("Authorization", format!("Bearer {}", jwt)) .send() .await