From 4b8540f03421155b48a2974a9fe9601bec3e678b Mon Sep 17 00:00:00 2001 From: Topvennie Date: Thu, 21 Nov 2024 15:06:03 +0100 Subject: [PATCH] vingo: add recent scans --- vingo/src/main.rs | 3 ++- vingo/src/routes/scans.rs | 31 +++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/vingo/src/main.rs b/vingo/src/main.rs index d8cacdb..61ae6a7 100644 --- a/vingo/src/main.rs +++ b/vingo/src/main.rs @@ -103,6 +103,8 @@ fn open_routes() -> Router { .route("/auth/callback", get(auth::callback)) .route("/scans", post(scans::add)) .route("/version", get(info::version)) + .route("/recent_scans", get(scans::recent)) + .route("/seasons", get(seasons::get_until_now)) } fn authenticated_routes() -> Router { @@ -118,7 +120,6 @@ fn authenticated_routes() -> Router { ) .route("/scans", get(scans::get_for_current_user)) .route("/leaderboard", get(leaderboard::get)) - .route("/seasons", get(seasons::get_until_now)) .route("/settings", get(settings::get).patch(settings::update)) .route_layer(from_fn(middleware::is_logged_in)) } diff --git a/vingo/src/routes/scans.rs b/vingo/src/routes/scans.rs index e211179..da2af6b 100644 --- a/vingo/src/routes/scans.rs +++ b/vingo/src/routes/scans.rs @@ -6,11 +6,13 @@ use crate::{ }; use axum::{extract::State, Json}; -use chrono::Local; +use chrono::{Local, Duration}; use reqwest::StatusCode; +use serde::{Serialize}; use sea_orm::{ ActiveModelTrait, ColumnTrait, EntityTrait, JoinType::InnerJoin, QueryFilter, QuerySelect, - RelationTrait, Set, + RelationTrait, Set, FromQueryResult, entity::prelude::DateTimeWithTimeZone, Statement, DbBackend, + Value }; use tower_sessions::Session; @@ -102,3 +104,28 @@ pub async fn add(state: State, body: String) -> ResponseResult Ok(user.name) } + +#[derive(Debug, FromQueryResult, Serialize)] +pub struct RecentScanItem { + id: i32, + scan_time: DateTimeWithTimeZone, +} + +pub async fn recent(state: State) -> ResponseResult>> { + let fourteen_days_ago = (Local::now() - Duration::days(14)).naive_local(); + let scans = RecentScanItem::find_by_statement(Statement::from_sql_and_values(DbBackend::Postgres, " + SELECT DISTINCT ON (s.user_id, DATE(s.scan_time)) s.id, s.scan_time + FROM ( + SELECT scan.id, scan.scan_time, \"user\".id as user_id + FROM scan + INNER JOIN card ON card.serial = scan.card_serial + INNER JOIN \"user\" ON \"user\".id = card.user_id + WHERE scan.scan_time > $1 + ) s + ORDER BY s.user_id, DATE(s.scan_time), s.id;", [Value::ChronoDateTime(Some(Box::new(fourteen_days_ago)))])) + .all(&state.db) + .await + .or_log((StatusCode::INTERNAL_SERVER_ERROR, "could not get all recent scans"))?; + + Ok(Json(scans)) +}