Skip to content

Commit

Permalink
feature: history endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
ParzivalEugene committed Aug 9, 2024
1 parent 5c035f8 commit 64fd036
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/data/enums/session_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use diesel::{
pg::{Pg, PgValue},
serialize::{self, IsNull, Output, ToSql},
};
use serde::{Deserialize, Serialize};
use std::io::Write;

#[derive(Debug, AsExpression, FromSqlRow, PartialEq, Eq, Clone, Copy)]
#[derive(Debug, AsExpression, FromSqlRow, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
#[diesel(sql_type = crate::data::schema::sql_types::SessionStatus)]
pub enum SessionStatus {
Active,
Expand Down
3 changes: 3 additions & 0 deletions src/dto/session/internal/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
pub mod new_session;
pub use new_session::NewSession;

Check warning on line 3 in src/dto/session/internal/mod.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/master-backend-rust/master-backend-rust/src/dto/session/internal/mod.rs
pub mod session_history;
pub use session_history::SessionHistory;
15 changes: 15 additions & 0 deletions src/dto/session/internal/session_history.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::data::enums::Country;

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SessionHistory {
pub id: Uuid,
pub device_id: Uuid,
pub opened_at: NaiveDateTime,
pub closed_at: NaiveDateTime,
pub duration: i64,
pub country: Country,
}
12 changes: 12 additions & 0 deletions src/dto/session/request/get_history.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use serde::Deserialize;
use uuid::Uuid;

use crate::data::enums::Country;

#[derive(Deserialize, Debug, Clone)]
pub struct Params {
pub limit: Option<i64>,
pub offset: Option<i64>,
pub countries: Option<Vec<Country>>,
pub devices: Option<Vec<Uuid>>,
}
3 changes: 3 additions & 0 deletions src/dto/session/request/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
pub mod create_session;
pub use create_session::CreateSession;

Check warning on line 3 in src/dto/session/request/mod.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/master-backend-rust/master-backend-rust/src/dto/session/request/mod.rs
pub mod get_history;
pub use get_history::Params;
26 changes: 26 additions & 0 deletions src/handlers/session/get_history.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use axum::{extract::State, http::StatusCode};
use deadpool_diesel::postgres::Pool;
use tracing::info;

use crate::{
dto::{
auth::internal::AccessToken,
response::success::Response,
session::{internal::SessionHistory, request::Params},
},
enums::errors::external::ExternalError,
extractors::Json,
services::session_service,
};

pub async fn get_history(
claims: AccessToken,
State(pool): State<Pool>,
Json(payload): Json<Params>,
) -> Result<Response<Vec<SessionHistory>>, ExternalError> {
info!("Getting session history");

let history = session_service::get_history(&pool, &claims.user_id, &payload).await?;

Ok(Response::new(StatusCode::OK, "Successfully got session history").with_data(history))
}
3 changes: 3 additions & 0 deletions src/handlers/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ pub use create_session::create_session;

pub mod close_session;
pub use close_session::close_session;

Check warning on line 6 in src/handlers/session/mod.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/master-backend-rust/master-backend-rust/src/handlers/session/mod.rs
pub mod get_history;
pub use get_history::get_history;
5 changes: 3 additions & 2 deletions src/routers/session_router.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use crate::{
handlers::session::{close_session, create_session},
handlers::session::{close_session, create_session, get_history},
AppState,
};
use axum::{
routing::{post, put},
routing::{get, post, put},
Router,
};

pub fn session_router(state: AppState) -> Router<AppState> {
Router::new()
.route("/", post(create_session))
.route("/", put(close_session))
.route("/history", get(get_history))
.with_state(state)
}
65 changes: 63 additions & 2 deletions src/services/session_service.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use crate::{
data::{
enums::{ConfigStatus, Country, SessionStatus},
models::Session,
models::{Config, Server, Session},
schema,
},
dto::session::{
interface::get_session,
internal::NewSession,
internal::{NewSession, SessionHistory},
query::{ActiveSessionAndDevice, ActiveSessionAndDeviceAndCountry},
request::Params,
response,
},
enums::errors::internal::{InternalError, SessionError},
Expand Down Expand Up @@ -118,3 +119,63 @@ pub async fn close_session(
let session_id = close_session_by_id(pool, &session.id).await?;
Ok(session_id)
}

pub async fn get_history(
pool: &deadpool_diesel::postgres::Pool,
user_id: &Uuid,
params: &Params,
) -> Result<Vec<SessionHistory>, InternalError> {
let conn = pool.get().await?;

let limit = params.limit.unwrap_or(10);
let offset = params.offset.unwrap_or(0);
let devices = params.devices.clone();
let countries = params.countries.clone();
let user_id = *user_id;

let data: Vec<(Session, Config, Server)> = conn
.interact(move |conn| {
schema::session::table
.inner_join(schema::config::table.inner_join(schema::server::table))
.filter(schema::session::status.eq(SessionStatus::Closed))
.filter(
schema::server::country.eq_any(
countries.unwrap_or(
schema::server::table
.select(schema::server::country)
.load::<Country>(conn)?,
),
),
)
.filter(
schema::session::device_id.eq_any(
devices.unwrap_or(
schema::device::table
.select(schema::device::id)
.filter(schema::device::user_id.eq(user_id))
.load::<Uuid>(conn)?,
),
),
)
.limit(limit)
.offset(offset)
.select((
Session::as_select(),
Config::as_select(),
Server::as_select(),
))
.load::<(Session, Config, Server)>(conn)
})
.await??;

let history = data.iter().map(|(session, _, server)| SessionHistory {
id: session.id,
device_id: session.device_id,
opened_at: session.opened_at,
closed_at: session.closed_at.unwrap(),
duration: (session.closed_at.unwrap() - session.opened_at).num_seconds(),
country: server.country,
});

Ok(history.collect())
}

0 comments on commit 64fd036

Please sign in to comment.