diff --git a/dsp-meta/src/api/handler/project_metadata_handler.rs b/dsp-meta/src/api/handler/project_metadata_handler.rs index f91f6eee..7f0b5ade 100644 --- a/dsp-meta/src/api/handler/project_metadata_handler.rs +++ b/dsp-meta/src/api/handler/project_metadata_handler.rs @@ -11,7 +11,7 @@ use crate::api::model::project_metadata_dto::{ProjectMetadataDto, ProjectMetadat use crate::api::model::project_metadata_graph_dto::ProjectMetadataGraphDto; use crate::app_state::AppState; use crate::domain::service::project_metadata_api_contract::ProjectMetadataApiContract; -use crate::domain::service::repository_contract::Pagination; +use crate::domain::service::repository_contract::{Filter, Pagination}; use crate::error::DspMetaError; /// GET /project_metadata/:shortcode @@ -54,10 +54,12 @@ pub async fn get_project_metadata_by_shortcode_as_rdf( pub async fn get_all_project_metadata( State(state): State>, pagination: Option>, + filter: Option>, ) -> Result { trace!("entered get_all_project_metadata()"); let Query(pagination) = pagination.unwrap_or_default(); - let page = state.project_metadata_service.find(&pagination)?; + let Query(filter) = filter.unwrap_or_default(); + let page = state.project_metadata_service.find(&filter, &pagination)?; let mut response = Json( page.data .into_iter() diff --git a/dsp-meta/src/domain/service/project_metadata_api_contract.rs b/dsp-meta/src/domain/service/project_metadata_api_contract.rs index 566db533..d304252f 100644 --- a/dsp-meta/src/domain/service/project_metadata_api_contract.rs +++ b/dsp-meta/src/domain/service/project_metadata_api_contract.rs @@ -1,10 +1,14 @@ use dsp_domain::metadata::value::Shortcode; use crate::api::convert::serde::draft_model::DraftMetadata; -use crate::domain::service::repository_contract::{Page, Pagination}; +use crate::domain::service::repository_contract::{Filter, Page, Pagination}; use crate::error::DspMetaError; pub trait ProjectMetadataApiContract { fn find_by_id(&self, id: Shortcode) -> Result, DspMetaError>; - fn find(&self, pagination: &Pagination) -> Result, DspMetaError>; + fn find( + &self, + filter: &Filter, + pagination: &Pagination, + ) -> Result, DspMetaError>; } diff --git a/dsp-meta/src/domain/service/project_metadata_service.rs b/dsp-meta/src/domain/service/project_metadata_service.rs index fb878f35..08fb0e4a 100644 --- a/dsp-meta/src/domain/service/project_metadata_service.rs +++ b/dsp-meta/src/domain/service/project_metadata_service.rs @@ -3,7 +3,7 @@ use tracing::{instrument, trace}; use crate::api::convert::serde::draft_model::DraftMetadata; use crate::domain::service::project_metadata_api_contract::ProjectMetadataApiContract; -use crate::domain::service::repository_contract::{Page, Pagination, RepositoryContract}; +use crate::domain::service::repository_contract::{Filter, Page, Pagination, RepositoryContract}; use crate::error::DspMetaError; #[derive(Debug, Clone)] @@ -30,7 +30,11 @@ where } #[instrument(skip(self))] - fn find(&self, pagination: &Pagination) -> Result, DspMetaError> { - self.repo.find(pagination) + fn find( + &self, + filter: &Filter, + pagination: &Pagination, + ) -> Result, DspMetaError> { + self.repo.find(filter, pagination) } } diff --git a/dsp-meta/src/domain/service/repository_contract.rs b/dsp-meta/src/domain/service/repository_contract.rs index 1b85ea80..4dd15460 100644 --- a/dsp-meta/src/domain/service/repository_contract.rs +++ b/dsp-meta/src/domain/service/repository_contract.rs @@ -13,11 +13,18 @@ impl Default for Pagination { } } +#[derive(Deserialize, Default, Debug)] +pub struct Filter { + #[serde(rename = "q")] + pub query: Option, + #[serde(rename = "filter")] + pub filter: Option, +} + pub struct Page { pub data: Vec, pub total: usize, } - /// The contract for the project metadata repository. /// It defines the methods that the repository must implement. /// The trait is generically typed for the entity type `Entity`, the id type `Id`, and @@ -28,7 +35,7 @@ pub trait RepositoryContract { fn find_by_id(&self, id: &Id) -> Result, Error>; /// Returns all entities. - fn find(&self, pagination: &Pagination) -> Result, Error>; + fn find(&self, filter: &Filter, pagination: &Pagination) -> Result, Error>; /// Returns the number of entities. fn count(&self) -> Result; diff --git a/dsp-meta/src/repo/service/project_metadata_repository.rs b/dsp-meta/src/repo/service/project_metadata_repository.rs index 38016489..3820cb16 100644 --- a/dsp-meta/src/repo/service/project_metadata_repository.rs +++ b/dsp-meta/src/repo/service/project_metadata_repository.rs @@ -6,8 +6,8 @@ use std::sync::{Arc, RwLock}; use dsp_domain::metadata::value::Shortcode; use tracing::{instrument, trace}; -use crate::api::convert::serde::draft_model::DraftMetadata; -use crate::domain::service::repository_contract::{Page, Pagination, RepositoryContract}; +use crate::api::convert::serde::draft_model::{DraftMetadata, DraftProjectStatus}; +use crate::domain::service::repository_contract::{Filter, Page, Pagination, RepositoryContract}; use crate::error::DspMetaError; use crate::infrastructure::load_json_file_paths; @@ -58,19 +58,46 @@ impl RepositoryContract for ProjectMetad } #[instrument(skip(self))] - fn find(&self, pagination: &Pagination) -> Result, DspMetaError> { - trace!("repository: find_all"); + fn find( + &self, + filter: &Filter, + pagination: &Pagination, + ) -> Result, DspMetaError> { let db = self.db.read().unwrap(); + let query_status: Option> = match filter.filter.as_deref() { + Some("o") => Some(vec![DraftProjectStatus::Ongoing]), + Some("f") => Some(vec![DraftProjectStatus::Finished]), + Some("of") => Some(vec![ + DraftProjectStatus::Ongoing, + DraftProjectStatus::Finished, + ]), + _ => None, + }; + let values = db .values() + .filter(|metadata| { + if let Some(query_status) = &query_status { + let actual_status = &metadata.project.status.clone().unwrap_or_default(); + !query_status.contains(actual_status) + } else { + true + } + }) + .filter(|metadata| { + if let Some(query) = &filter.query { + serde_json::to_string(metadata).unwrap().contains(query) + } else { + true + } + }).cloned().collect::>(); + let total = values.len(); + let data = values + .into_iter() .skip((pagination.page - 1) * pagination.limit) - .take(pagination.limit); - let result = values.cloned().collect(); - let total = self.count()?; - Ok(Page { - data: result, - total, - }) + .take(pagination.limit) + .collect::>(); + Ok(Page { data, total }) } fn count(&self) -> Result {