diff --git a/src/endpoints/analytics/get_quest_activity.rs b/src/endpoints/analytics/get_quest_activity.rs index acc48c0a..2c9e571a 100644 --- a/src/endpoints/analytics/get_quest_activity.rs +++ b/src/endpoints/analytics/get_quest_activity.rs @@ -17,14 +17,15 @@ pub struct GetQuestsQuery { } #[route( - get, - "/analytics/get_quest_activity", - crate::endpoints::analytics::get_quest_activity +get, +"/analytics/get_quest_activity", +crate::endpoints::analytics::get_quest_activity )] pub async fn handler( State(state): State>, Query(query): Query, ) -> impl IntoResponse { + let current_time = chrono::Utc::now().timestamp_millis(); let quest_id = query.id; let day_wise_distribution = vec![ doc! { @@ -32,9 +33,29 @@ pub async fn handler( "quest_id": quest_id } }, + doc! { + "$lookup": doc! { + "from": "quests", + "localField": "quest_id", + "foreignField": "id", + "as": "questDetails" + } + }, + doc! { + "$set": doc! { + "expiry": doc! { + "$arrayElemAt": [ + "$questDetails.expiry", + 0 + ] + } + } + }, doc! { "$group": doc! { - "_id": null, + "_id": doc! { + "expiry": "$expiry" + }, "ids": doc! { "$push": "$id" } @@ -43,8 +64,37 @@ pub async fn handler( doc! { "$lookup": doc! { "from": "completed_tasks", - "localField": "ids", - "foreignField": "task_id", + "let": doc! { + "localIds": "$ids", + "expiry": "$_id.expiry" + }, + "pipeline": [ + doc! { + "$match": doc! { + "$expr": doc! { + "$and": [ + doc! { + "$in": [ + "$task_id", + "$$localIds" + ] + }, + doc! { + "$lte": [ + "$timestamp", + doc! { + "$ifNull": [ + "$$expiry", + current_time + ] + } + ] + } + ] + } + } + } + ], "as": "matching_documents" } }, diff --git a/src/endpoints/analytics/get_quest_participation.rs b/src/endpoints/analytics/get_quest_participation.rs index 825e8a4b..c9a6afec 100644 --- a/src/endpoints/analytics/get_quest_participation.rs +++ b/src/endpoints/analytics/get_quest_participation.rs @@ -17,14 +17,15 @@ pub struct GetQuestsQuery { } #[route( -get, -"/analytics/get_quest_participation", -crate::endpoints::analytics::get_quest_participation + get, + "/analytics/get_quest_participation", + crate::endpoints::analytics::get_quest_participation )] pub async fn handler( State(state): State>, Query(query): Query, ) -> impl IntoResponse { + let current_time = chrono::Utc::now().timestamp_millis(); let quest_id = query.id; let day_wise_distribution = vec![ doc! { @@ -32,9 +33,29 @@ pub async fn handler( "quest_id": quest_id } }, + doc! { + "$lookup": doc! { + "from": "quests", + "localField": "quest_id", + "foreignField": "id", + "as": "questDetails" + } + }, + doc! { + "$set": doc! { + "expiry": doc! { + "$arrayElemAt": [ + "$questDetails.expiry", + 0 + ] + } + } + }, doc! { "$group": doc! { - "_id": null, + "_id": doc! { + "expiry": "$expiry" + }, "ids": doc! { "$push": "$id" }, @@ -46,8 +67,37 @@ pub async fn handler( doc! { "$lookup": doc! { "from": "completed_tasks", - "localField": "ids", - "foreignField": "task_id", + "let": doc! { + "localIds": "$ids", + "expiry": "$_id.expiry" + }, + "pipeline": [ + doc! { + "$match": doc! { + "$expr": doc! { + "$and": [ + doc! { + "$in": [ + "$task_id", + "$$localIds" + ] + }, + doc! { + "$lte": [ + "$timestamp", + doc! { + "$ifNull": [ + "$$expiry", + current_time + ] + } + ] + } + ] + } + } + } + ], "as": "matching_documents" } }, @@ -93,24 +143,25 @@ pub async fn handler( "$matching_documents", "$otherDetails", doc! { - "participants": "$count" + "count": "$count" } ] } } }, doc! { - "$project": doc! { - "otherDetails": 0, - "_id":0, - "verify_endpoint": 0, - "verify_endpoint_type": 0, - "verify_redirect":0, - "href": 0, - "cta": 0, - "id": 0, - "quest_id": 0, - + "$project": doc! { + "otherDetails": 0, + "_id":0, + "verify_endpoint": 0, + "verify_endpoint_type": 0, + "verify_redirect":0, + "href": 0, + "cta": 0, + "id": 0, + "quest_id": 0, + "questDetails": 0, + "expiry":0 } }, ]; diff --git a/src/endpoints/get_quest.rs b/src/endpoints/get_quest.rs index a3ab39e4..047e573b 100644 --- a/src/endpoints/get_quest.rs +++ b/src/endpoints/get_quest.rs @@ -25,11 +25,12 @@ pub async fn handler( Query(query): Query, ) -> impl IntoResponse { let collection = state.db.collection::("quests"); + let pipeline = [ doc! { "$match": { "disabled": false, - "id": query.id + "id": query.id, } }, doc! { @@ -38,8 +39,18 @@ pub async fn handler( "$cond": [ { "$and": [ - { "$gte": ["$expiry", 0] }, - { "$lt": ["$expiry", "$$NOW"] }, + doc! { + "$gte": [ + "$expiry", + 0 + ] + }, + doc! { + "$lt": [ + "$expiry", + "$$NOW" + ] + } ] }, true, @@ -57,8 +68,7 @@ pub async fn handler( Ok(document) => { if let Ok(mut quest) = from_document::(document) { if let Some(expiry) = &quest.expiry { - let timestamp = expiry.timestamp_millis().to_string(); - quest.expiry_timestamp = Some(timestamp); + quest.expiry_timestamp = Some(expiry.to_string()); } return (StatusCode::OK, Json(quest)).into_response(); } diff --git a/src/endpoints/get_quests.rs b/src/endpoints/get_quests.rs index e629b027..0c71dbfe 100644 --- a/src/endpoints/get_quests.rs +++ b/src/endpoints/get_quests.rs @@ -23,11 +23,15 @@ pub struct NFTItem { #[route(get, "/get_quests", crate::endpoints::get_quests)] pub async fn handler(State(state): State>) -> impl IntoResponse { + let current_time = chrono::Utc::now().timestamp_millis(); + let pipeline = vec![ doc! { "$match": { "disabled": false, - "hidden": false, + "start_time": { + "$lte":current_time + } } }, doc! { @@ -36,8 +40,18 @@ pub async fn handler(State(state): State>) -> impl IntoResponse { "$cond": [ { "$and": [ - { "$gte": ["$expiry", 0] }, - { "$lt": ["$expiry", "$$NOW"] }, + doc! { + "$gte": [ + "$expiry", + 0 + ] + }, + doc! { + "$lt": [ + "$expiry", + "$$NOW" + ] + } ] }, true, @@ -57,8 +71,7 @@ pub async fn handler(State(state): State>) -> impl IntoResponse { Ok(document) => { if let Ok(mut quest) = from_document::(document) { if let Some(expiry) = &quest.expiry { - let timestamp = expiry.timestamp_millis().to_string(); - quest.expiry_timestamp = Some(timestamp); + quest.expiry_timestamp = Some(expiry.to_string()); } quests.push(quest); } diff --git a/src/endpoints/get_trending_quests.rs b/src/endpoints/get_trending_quests.rs index 75276946..8ec03cf0 100644 --- a/src/endpoints/get_trending_quests.rs +++ b/src/endpoints/get_trending_quests.rs @@ -30,12 +30,16 @@ pub async fn handler( Some(addr) => addr.to_string(), None => "".to_string(), }; + let current_time = chrono::Utc::now().timestamp_millis(); + let mut pipeline = vec![ doc! { "$match": { "disabled": false, - "hidden": false, "is_trending": true, + "start_time": doc! { + "$lte": current_time + } } }, doc! { diff --git a/src/models.rs b/src/models.rs index c171505a..db7832f8 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,4 +1,4 @@ -use mongodb::{bson, Database}; +use mongodb::{Database}; use serde::{Deserialize, Serialize}; use serde_json::Value; use starknet::{ @@ -34,13 +34,15 @@ pub_struct!(Debug, Serialize, Deserialize; QuestDocument { rewards_nfts: Vec, img_card: String, title_card: String, - hidden: bool, + hidden: Option, disabled: bool, - expiry: Option, + expiry: Option, expiry_timestamp: Option, mandatory_domain: Option, expired: Option, experience: i64, + start_time: i64, + }); pub_struct!(Deserialize; CompletedTasks {