From 12c7c8f6ee5d2371677a643bee63c5e5d0eb39b4 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sun, 28 May 2023 17:17:22 +0200 Subject: [PATCH] feat: working projects and items Signed-off-by: kjuulh --- como_core/src/items/mod.rs | 19 ++++++---- como_domain/src/item/mod.rs | 1 + como_domain/src/item/queries.rs | 2 +- como_domain/src/item/requests.rs | 4 ++ como_domain/src/projects/queries.rs | 3 +- como_gql/src/graphql.rs | 12 ++++-- como_gql/src/items.rs | 14 +++++-- como_gql/src/projects.rs | 38 ++++++++++++++++++- .../src/services/item_service.rs | 32 ++++++++++------ .../src/services/project_service.rs | 12 ++---- 10 files changed, 98 insertions(+), 39 deletions(-) diff --git a/como_core/src/items/mod.rs b/como_core/src/items/mod.rs index 0d1e940..3df4696 100644 --- a/como_core/src/items/mod.rs +++ b/como_core/src/items/mod.rs @@ -1,18 +1,21 @@ use std::sync::Arc; use async_trait::async_trait; -use como_domain::item::{ - queries::{GetItemQuery, GetItemsQuery}, - requests::CreateItemDto, - responses::CreatedItemDto, - ItemDto, +use como_domain::{ + item::{ + queries::{GetItemQuery, GetItemsQuery}, + requests::CreateItemDto, + responses::CreatedItemDto, + ItemDto, + }, + users::User, }; pub type DynItemService = Arc; #[async_trait] pub trait ItemService { - async fn add_item(&self, item: CreateItemDto) -> anyhow::Result; - async fn get_item(&self, query: GetItemQuery) -> anyhow::Result; - async fn get_items(&self, query: GetItemsQuery) -> anyhow::Result>; + async fn add_item(&self, item: CreateItemDto, user: &User) -> anyhow::Result; + async fn get_item(&self, query: GetItemQuery, user: &User) -> anyhow::Result; + async fn get_items(&self, query: GetItemsQuery, user: &User) -> anyhow::Result>; } diff --git a/como_domain/src/item/mod.rs b/como_domain/src/item/mod.rs index 306e545..2d2a64b 100644 --- a/como_domain/src/item/mod.rs +++ b/como_domain/src/item/mod.rs @@ -20,4 +20,5 @@ pub struct ItemDto { pub title: String, pub description: Option, pub state: ItemState, + pub project_id: Uuid, } diff --git a/como_domain/src/item/queries.rs b/como_domain/src/item/queries.rs index c0f8aeb..1293480 100644 --- a/como_domain/src/item/queries.rs +++ b/como_domain/src/item/queries.rs @@ -9,5 +9,5 @@ pub struct GetItemQuery { #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, InputObject)] pub struct GetItemsQuery { - pub user_id: Uuid, + pub project_id: Uuid, } diff --git a/como_domain/src/item/requests.rs b/como_domain/src/item/requests.rs index a11bd02..48e83d8 100644 --- a/como_domain/src/item/requests.rs +++ b/como_domain/src/item/requests.rs @@ -1,7 +1,11 @@ use async_graphql::InputObject; use serde::{Deserialize, Serialize}; +use uuid::Uuid; #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, InputObject)] pub struct CreateItemDto { pub name: String, + pub description: Option, + + pub project_id: Uuid, } diff --git a/como_domain/src/projects/queries.rs b/como_domain/src/projects/queries.rs index 7a67da5..90dc866 100644 --- a/como_domain/src/projects/queries.rs +++ b/como_domain/src/projects/queries.rs @@ -4,6 +4,5 @@ use uuid::Uuid; #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, InputObject)] pub struct GetProjectQuery { - pub project_id: Option, - pub item_id: Option, + pub project_id: Uuid, } diff --git a/como_gql/src/graphql.rs b/como_gql/src/graphql.rs index 7c8384e..14f9079 100644 --- a/como_gql/src/graphql.rs +++ b/como_gql/src/graphql.rs @@ -19,9 +19,11 @@ impl MutationRoot { ctx: &Context<'_>, item: CreateItemDto, ) -> anyhow::Result { + let user = ctx.data_unchecked::(); + let services_register = ctx.data_unchecked::(); - let created_item = services_register.item_service.add_item(item).await?; + let created_item = services_register.item_service.add_item(item, user).await?; Ok(CreatedItem { id: created_item.id, @@ -51,10 +53,12 @@ pub struct QueryRoot; #[Object] impl QueryRoot { async fn get_item(&self, ctx: &Context<'_>, query: GetItemQuery) -> anyhow::Result { + let user = ctx.data_unchecked::(); + let item = ctx .data_unchecked::() .item_service - .get_item(query) + .get_item(query, user) .await?; Ok(Item::from(item)) @@ -65,10 +69,12 @@ impl QueryRoot { ctx: &Context<'_>, query: GetItemsQuery, ) -> anyhow::Result> { + let user = ctx.data_unchecked::(); + let items = ctx .data_unchecked::() .item_service - .get_items(query) + .get_items(query, user) .await?; Ok(items.iter().map(|i| Item::from(i.clone())).collect()) diff --git a/como_gql/src/items.rs b/como_gql/src/items.rs index 61f25bc..85b4ef7 100644 --- a/como_gql/src/items.rs +++ b/como_gql/src/items.rs @@ -2,6 +2,7 @@ use async_graphql::{Context, Object}; use como_domain::{ item::{queries::GetItemQuery, ItemDto, ItemState}, projects::queries::GetProjectQuery, + users::User, }; use como_infrastructure::register::ServiceRegister; use uuid::Uuid; @@ -15,10 +16,12 @@ pub struct CreatedItem { #[Object] impl CreatedItem { pub async fn item(&self, ctx: &Context<'_>) -> anyhow::Result { + let user = ctx.data_unchecked::(); + let item = ctx .data_unchecked::() .item_service - .get_item(GetItemQuery { item_id: self.id }) + .get_item(GetItemQuery { item_id: self.id }, user) .await?; Ok(item.into()) @@ -30,6 +33,7 @@ pub struct Item { pub title: String, pub description: Option, pub state: ItemState, + pub project_id: Uuid, } #[Object] @@ -55,13 +59,16 @@ impl Item { .data_unchecked::() .project_service .get_project(GetProjectQuery { - item_id: Some(self.id), - project_id: None, + project_id: self.project_id, }) .await?; Ok(project.into()) } + + pub async fn project_id(&self, _ctx: &Context<'_>) -> anyhow::Result { + return Ok(self.project_id); + } } impl From for Item { @@ -71,6 +78,7 @@ impl From for Item { title: dto.title, description: dto.description, state: dto.state, + project_id: dto.project_id, } } } diff --git a/como_gql/src/projects.rs b/como_gql/src/projects.rs index 12efea2..c034536 100644 --- a/como_gql/src/projects.rs +++ b/como_gql/src/projects.rs @@ -1,13 +1,47 @@ -use async_graphql::SimpleObject; +use async_graphql::{Context, Object}; use como_domain::projects::ProjectDto; +use como_domain::users::User; +use como_infrastructure::register::ServiceRegister; use uuid::Uuid; -#[derive(SimpleObject)] +use crate::items::Item; + pub struct Project { pub id: Uuid, pub name: String, } +#[Object] +impl Project { + async fn id(&self) -> &Uuid { + &self.id + } + + async fn name(&self) -> &String { + &self.name + } + + async fn items(&self, ctx: &Context<'_>) -> anyhow::Result> { + let user = ctx.data_unchecked::(); + + let items = ctx + .data_unchecked::() + .item_service + .get_items( + como_domain::item::queries::GetItemsQuery { + project_id: self.id, + }, + user, + ) + .await? + .iter() + .map(|i| Item::from(i.clone())) + .collect::>(); + + Ok(items) + } +} + impl From for Project { fn from(dto: ProjectDto) -> Self { Self { diff --git a/como_infrastructure/src/services/item_service.rs b/como_infrastructure/src/services/item_service.rs index 1b2f5a0..3813cdc 100644 --- a/como_infrastructure/src/services/item_service.rs +++ b/como_infrastructure/src/services/item_service.rs @@ -5,11 +5,14 @@ use std::{ use async_trait::async_trait; use como_core::items::ItemService; -use como_domain::item::{ - queries::{GetItemQuery, GetItemsQuery}, - requests::CreateItemDto, - responses::CreatedItemDto, - ItemDto, +use como_domain::{ + item::{ + queries::{GetItemQuery, GetItemsQuery}, + requests::CreateItemDto, + responses::CreatedItemDto, + ItemDto, + }, + users::User, }; use uuid::Uuid; @@ -23,15 +26,15 @@ impl DefaultItemService { #[async_trait] impl ItemService for DefaultItemService { - async fn add_item(&self, _item: CreateItemDto) -> anyhow::Result { + async fn add_item(&self, _item: CreateItemDto, user: &User) -> anyhow::Result { todo!() } - async fn get_item(&self, _query: GetItemQuery) -> anyhow::Result { + async fn get_item(&self, _query: GetItemQuery, user: &User) -> anyhow::Result { todo!() } - async fn get_items(&self, _query: GetItemsQuery) -> anyhow::Result> { + async fn get_items(&self, _query: GetItemsQuery, user: &User) -> anyhow::Result> { todo!() } } @@ -50,13 +53,18 @@ impl MemoryItemService { #[async_trait] impl ItemService for MemoryItemService { - async fn add_item(&self, create_item: CreateItemDto) -> anyhow::Result { + async fn add_item( + &self, + create_item: CreateItemDto, + user: &User, + ) -> anyhow::Result { if let Ok(mut item_store) = self.item_store.lock() { let item = ItemDto { id: Uuid::new_v4(), title: create_item.name, - description: None, + description: create_item.description, state: como_domain::item::ItemState::Created, + project_id: create_item.project_id, }; item_store.insert(item.id.to_string(), item.clone()); @@ -67,7 +75,7 @@ impl ItemService for MemoryItemService { } } - async fn get_item(&self, query: GetItemQuery) -> anyhow::Result { + async fn get_item(&self, query: GetItemQuery, user: &User) -> anyhow::Result { if let Ok(item_store) = self.item_store.lock() { let item = item_store .get(&query.item_id.to_string()) @@ -78,7 +86,7 @@ impl ItemService for MemoryItemService { } } - async fn get_items(&self, _query: GetItemsQuery) -> anyhow::Result> { + async fn get_items(&self, _query: GetItemsQuery, user: &User) -> anyhow::Result> { todo!() } } diff --git a/como_infrastructure/src/services/project_service.rs b/como_infrastructure/src/services/project_service.rs index 845a4df..d9cf1f8 100644 --- a/como_infrastructure/src/services/project_service.rs +++ b/como_infrastructure/src/services/project_service.rs @@ -49,14 +49,10 @@ impl MemoryProjectService { impl ProjectService for MemoryProjectService { async fn get_project(&self, query: GetProjectQuery) -> anyhow::Result { let ps = self.project_store.lock().await; - if let Some(item_id) = query.item_id { - Ok(ps - .get(&item_id.to_string()) - .ok_or(anyhow::anyhow!("could not find project"))? - .clone()) - } else { - Err(anyhow::anyhow!("could not find project")) - } + Ok(ps + .get(&query.project_id.to_string()) + .ok_or(anyhow::anyhow!("could not find project"))? + .clone()) } async fn get_projects(&self, user: &User) -> anyhow::Result> { Ok(self