diff --git a/Cargo.lock b/Cargo.lock index 0008361..1446e68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,12 +12,6 @@ dependencies = [ "regex", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "aead" version = "0.5.2" @@ -84,21 +78,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "android-tzdata" version = "0.1.1" @@ -169,17 +148,6 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" -[[package]] -name = "argon2" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4ce4441f99dbd377ca8a8f57b698c44d0d6e712d8329b5040da5a64aa1ce73" -dependencies = [ - "base64ct", - "blake2", - "password-hash 0.4.2", -] - [[package]] name = "argon2" version = "0.5.0" @@ -188,7 +156,7 @@ checksum = "95c2fcf79ad1932ac6269a738109997a83c227c09b75842ae564dc8ede6a861c" dependencies = [ "base64ct", "blake2", - "password-hash 0.5.0", + "password-hash", ] [[package]] @@ -220,20 +188,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-compression" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" -dependencies = [ - "brotli", - "flate2", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", -] - [[package]] name = "async-executor" version = "1.5.1" @@ -603,7 +557,7 @@ dependencies = [ "axum", "axum-core", "bytes", - "cookie 0.17.0", + "cookie", "futures-util", "http", "http-body", @@ -612,7 +566,7 @@ dependencies = [ "serde", "tokio", "tower", - "tower-http 0.4.0", + "tower-http", "tower-layer", "tower-service", ] @@ -657,12 +611,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" -[[package]] -name = "base64" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" - [[package]] name = "base64" version = "0.21.2" @@ -756,27 +704,6 @@ dependencies = [ "log", ] -[[package]] -name = "brotli" -version = "3.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - [[package]] name = "bumpalo" version = "3.13.0" @@ -905,7 +832,6 @@ dependencies = [ "como_domain", "como_gql", "como_infrastructure", - "dotenv", "oauth2", "openidconnect", "serde", @@ -913,7 +839,7 @@ dependencies = [ "sqlx 0.6.3", "tokio", "tower", - "tower-http 0.4.0", + "tower-http", "tracing", "uuid", "zitadel", @@ -951,7 +877,6 @@ dependencies = [ name = "como_domain" version = "0.1.0" dependencies = [ - "anyhow", "async-graphql", "serde", "serde_json", @@ -963,25 +888,11 @@ name = "como_gql" version = "0.1.0" dependencies = [ "anyhow", - "argon2 0.4.1", "async-graphql", - "async-graphql-axum", - "axum", - "axum-extra", - "axum-sessions", + "async-trait", "como_core", "como_domain", "como_infrastructure", - "cookie 0.16.2", - "dotenv", - "rand_core", - "serde", - "serde_json", - "sqlx 0.6.3", - "tokio", - "tower-http 0.3.5", - "tracing", - "tracing-subscriber", "uuid", ] @@ -990,7 +901,7 @@ name = "como_infrastructure" version = "0.1.0" dependencies = [ "anyhow", - "argon2 0.5.0", + "argon2", "async-sqlx-session", "async-trait", "axum", @@ -1027,24 +938,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "aes-gcm", - "base64 0.20.0", - "hkdf", - "hmac 0.12.1", - "percent-encoding", - "rand", - "sha2 0.10.6", - "subtle", - "time 0.3.21", - "version_check", -] - [[package]] name = "cookie" version = "0.17.0" @@ -1117,15 +1010,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if 1.0.0", -] - [[package]] name = "crossbeam-queue" version = "0.3.8" @@ -1456,16 +1340,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" -[[package]] -name = "flate2" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1987,15 +1861,6 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" -[[package]] -name = "iri-string" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0f7638c1e223529f1bfdc48c8b133b9e0b434094d1d28473161ee48b235f78" -dependencies = [ - "nom", -] - [[package]] name = "is-terminal" version = "0.4.7" @@ -2137,31 +2002,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - [[package]] name = "mio" version = "0.8.8" @@ -2326,9 +2172,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.2" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -2502,17 +2348,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core", - "subtle", -] - [[package]] name = "password-hash" version = "0.5.0" @@ -3836,36 +3671,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "tower-http" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" -dependencies = [ - "async-compression", - "base64 0.13.1", - "bitflags", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "httpdate", - "iri-string", - "mime", - "mime_guess", - "percent-encoding", - "pin-project-lite", - "tokio", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "uuid", -] - [[package]] name = "tower-http" version = "0.4.0" @@ -3997,15 +3802,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.13" diff --git a/como_api/Cargo.toml b/como_api/Cargo.toml index f076fb5..01fce51 100644 --- a/como_api/Cargo.toml +++ b/como_api/Cargo.toml @@ -22,7 +22,6 @@ tokio.workspace = true uuid.workspace = true sqlx.workspace = true anyhow.workspace = true -dotenv.workspace = true tracing.workspace = true async-sqlx-session.workspace = true diff --git a/como_core/report.json b/como_core/report.json new file mode 100644 index 0000000..a0ea548 --- /dev/null +++ b/como_core/report.json @@ -0,0 +1,5 @@ +{ + "version": 0, + "root_name": "Workspace", + "workspace_crates": {} +} \ No newline at end of file diff --git a/como_core/src/items/mod.rs b/como_core/src/items/mod.rs index ad85673..3dc518c 100644 --- a/como_core/src/items/mod.rs +++ b/como_core/src/items/mod.rs @@ -4,7 +4,7 @@ use async_trait::async_trait; use como_domain::{ item::{ queries::{GetItemQuery, GetItemsQuery}, - requests::CreateItemDto, + requests::{CreateItemDto, UpdateItemDto}, responses::CreatedItemDto, ItemDto, }, @@ -26,4 +26,6 @@ pub trait ItemService { context: &Context, query: GetItemsQuery, ) -> anyhow::Result>; + + async fn update_item(&self, context: &Context, item: UpdateItemDto) -> anyhow::Result; } diff --git a/como_domain/Cargo.toml b/como_domain/Cargo.toml index 7b425d8..ede6ca8 100644 --- a/como_domain/Cargo.toml +++ b/como_domain/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" [dependencies] async-graphql.workspace = true -anyhow.workspace = true serde.workspace = true serde_json.workspace = true uuid.workspace = true diff --git a/como_domain/src/item/requests.rs b/como_domain/src/item/requests.rs index 48e83d8..b1c731c 100644 --- a/como_domain/src/item/requests.rs +++ b/como_domain/src/item/requests.rs @@ -2,10 +2,20 @@ use async_graphql::InputObject; use serde::{Deserialize, Serialize}; use uuid::Uuid; +use super::ItemState; + #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, InputObject)] pub struct CreateItemDto { - pub name: String, + pub title: String, pub description: Option, - pub project_id: Uuid, } + +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, InputObject)] +pub struct UpdateItemDto { + pub id: Uuid, + pub title: Option, + pub description: Option, + pub state: Option, + pub project_id: Option, +} diff --git a/como_gql/Cargo.toml b/como_gql/Cargo.toml index edd933e..1c1318b 100644 --- a/como_gql/Cargo.toml +++ b/como_gql/Cargo.toml @@ -6,31 +6,11 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -como_core = { path = "../como_core" } -como_domain = { path = "../como_domain" } -como_infrastructure = { path = "../como_infrastructure" } +como_core.workspace = true +como_domain.workspace = true +como_infrastructure.workspace = true -async-graphql = "5.0.9" -async-graphql-axum = "5.0.9" -axum.workspace = true -axum-extra = { version = "*", features = ["cookie", "cookie-private"] } -axum-sessions = { version = "*" } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0.68" -tokio = { version = "1.20.1", features = ["full"] } -uuid = { version = "1.1.2", features = ["v4", "fast-rng"] } -sqlx = { version = "0.6", features = [ - "runtime-tokio-rustls", - "postgres", - "migrate", - "uuid", - "offline", -] } -anyhow = "1.0.60" -dotenv = "0.15.0" -tracing = "0.1.36" -tracing-subscriber = { version = "0.3.15", features = ["env-filter"] } -tower-http = { version = "0.3.4", features = ["full"] } -argon2 = "0.4" -rand_core = { version = "0.6", features = ["std"] } -cookie = { version = "0.16", features = ["secure", "percent-encode"] } +anyhow.workspace = true +async-trait.workspace = true +async-graphql.workspace = true +uuid.workspace = true diff --git a/como_gql/src/graphql.rs b/como_gql/src/graphql.rs index 336652c..7abf5da 100644 --- a/como_gql/src/graphql.rs +++ b/como_gql/src/graphql.rs @@ -1,13 +1,12 @@ +use crate::common::*; use crate::items::{CreatedItem, Item}; use async_graphql::{Context, EmptySubscription, Object, Schema}; use como_domain::item::queries::{GetItemQuery, GetItemsQuery}; -use como_domain::item::requests::CreateItemDto; +use como_domain::item::requests::{CreateItemDto, UpdateItemDto}; use como_domain::projects::mutation::CreateProjectMutation; use como_domain::projects::queries::GetProjectQuery; use como_domain::projects::ProjectDto; -use como_infrastructure::register::ServiceRegister; - pub type ComoSchema = Schema; pub struct MutationRoot; @@ -19,13 +18,8 @@ impl MutationRoot { ctx: &Context<'_>, item: CreateItemDto, ) -> anyhow::Result { - let context = ctx.data_unchecked::(); - - let services_register = ctx.data_unchecked::(); - - let created_item = services_register - .item_service - .add_item(context, item) + let created_item = item_service(ctx) + .add_item(get_domain_context(ctx), item) .await?; Ok(CreatedItem { @@ -38,17 +32,20 @@ impl MutationRoot { ctx: &Context<'_>, request: CreateProjectMutation, ) -> anyhow::Result { - let context = ctx.data_unchecked::(); - - let services_register = ctx.data_unchecked::(); - - let project = services_register - .project_service - .create_project(context, request) + let project = project_service(ctx) + .create_project(get_domain_context(ctx), request) .await?; Ok(project) } + + async fn update_item(&self, ctx: &Context<'_>, item: UpdateItemDto) -> anyhow::Result { + let updated_item = item_service(ctx) + .update_item(get_domain_context(ctx), item) + .await?; + + Ok(updated_item.into()) + } } pub struct QueryRoot; @@ -56,12 +53,8 @@ pub struct QueryRoot; #[Object] impl QueryRoot { async fn get_item(&self, ctx: &Context<'_>, query: GetItemQuery) -> anyhow::Result { - let context = ctx.data_unchecked::(); - - let item = ctx - .data_unchecked::() - .item_service - .get_item(context, query) + let item = item_service(ctx) + .get_item(get_domain_context(ctx), query) .await?; Ok(Item::from(item)) @@ -72,12 +65,8 @@ impl QueryRoot { ctx: &Context<'_>, query: GetItemsQuery, ) -> anyhow::Result> { - let context = ctx.data_unchecked::(); - - let items = ctx - .data_unchecked::() - .item_service - .get_items(context, query) + let items = item_service(ctx) + .get_items(get_domain_context(ctx), query) .await?; Ok(items.iter().map(|i| Item::from(i.clone())).collect()) @@ -89,20 +78,14 @@ impl QueryRoot { ctx: &Context<'_>, query: GetProjectQuery, ) -> anyhow::Result { - let context = ctx.data_unchecked::(); - - ctx.data_unchecked::() - .project_service - .get_project(context, query) + project_service(ctx) + .get_project(get_domain_context(ctx), query) .await } async fn get_projects(&self, ctx: &Context<'_>) -> anyhow::Result> { - let context = ctx.data_unchecked::(); - - ctx.data_unchecked::() - .project_service - .get_projects(context) + project_service(ctx) + .get_projects(get_domain_context(ctx)) .await } } diff --git a/como_gql/src/items.rs b/como_gql/src/items.rs index 624daf3..b71cdc9 100644 --- a/como_gql/src/items.rs +++ b/como_gql/src/items.rs @@ -1,9 +1,9 @@ +use crate::common::*; use async_graphql::{Context, Object}; use como_domain::{ item::{queries::GetItemQuery, ItemDto, ItemState}, projects::queries::GetProjectQuery, }; -use como_infrastructure::register::ServiceRegister; use uuid::Uuid; use crate::projects::Project; @@ -15,12 +15,8 @@ pub struct CreatedItem { #[Object] impl CreatedItem { pub async fn item(&self, ctx: &Context<'_>) -> anyhow::Result { - let context = ctx.data_unchecked::(); - - let item = ctx - .data_unchecked::() - .item_service - .get_item(context, GetItemQuery { item_id: self.id }) + let item = item_service(ctx) + .get_item(get_domain_context(ctx), GetItemQuery { item_id: self.id }) .await?; Ok(item.into()) @@ -54,12 +50,9 @@ impl Item { } pub async fn project(&self, ctx: &Context<'_>) -> anyhow::Result { - let context = ctx.data_unchecked::(); - let project = ctx - .data_unchecked::() - .project_service + let project = project_service(ctx) .get_project( - context, + get_domain_context(ctx), GetProjectQuery { project_id: self.project_id, }, diff --git a/como_gql/src/lib.rs b/como_gql/src/lib.rs index fff31a7..b36a626 100644 --- a/como_gql/src/lib.rs +++ b/como_gql/src/lib.rs @@ -1,3 +1,33 @@ pub mod graphql; mod items; mod projects; + +pub mod common { + use async_graphql::Context; + use como_core::items::DynItemService; + use como_core::projects::DynProjectService; + use como_infrastructure::register::ServiceRegister; + + #[inline(always)] + pub(crate) fn get_domain_context<'a>(ctx: &Context<'a>) -> &'a como_domain::Context { + ctx.data_unchecked::() + } + + #[allow(dead_code)] + #[inline(always)] + pub(crate) fn get_service_register<'a>(ctx: &Context<'a>) -> &'a ServiceRegister { + ctx.data_unchecked::() + } + + #[inline(always)] + pub(crate) fn project_service<'a>(ctx: &Context<'a>) -> DynProjectService { + ctx.data_unchecked::() + .project_service + .clone() + } + + #[inline(always)] + pub(crate) fn item_service<'a>(ctx: &Context<'a>) -> DynItemService { + ctx.data_unchecked::().item_service.clone() + } +} diff --git a/como_gql/src/projects.rs b/como_gql/src/projects.rs index ddd943b..424895b 100644 --- a/como_gql/src/projects.rs +++ b/como_gql/src/projects.rs @@ -1,7 +1,7 @@ +use crate::common::*; use async_graphql::{Context, Object}; use como_domain::projects::ProjectDto; -use como_infrastructure::register::ServiceRegister; use uuid::Uuid; use crate::items::Item; @@ -22,13 +22,9 @@ impl Project { } async fn items(&self, ctx: &Context<'_>) -> anyhow::Result> { - let context = ctx.data_unchecked::(); - - let items = ctx - .data_unchecked::() - .item_service + let items = item_service(ctx) .get_items( - context, + get_domain_context(ctx), como_domain::item::queries::GetItemsQuery { project_id: self.id, }, diff --git a/como_infrastructure/.sqlx/.gitkeep b/como_infrastructure/.sqlx/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/como_infrastructure/build.rs b/como_infrastructure/build.rs new file mode 100644 index 0000000..0fb3776 --- /dev/null +++ b/como_infrastructure/build.rs @@ -0,0 +1,9 @@ +fn main() { + println!("cargo:rustc-env=SQLX_OFFLINE_DIR='./.sqlx'"); + // When building in docs.rs, we want to set SQLX_OFFLINE mode to true + if std::env::var_os("DOCS_RS").is_some() { + println!("cargo:rustc-env=SQLX_OFFLINE=true"); + } else if std::env::var_os("DOCKER_BUILD").is_some() { + println!("cargo:rustc-env=SQLX_OFFLINE=true"); + } +} diff --git a/como_infrastructure/sqlx-data.json b/como_infrastructure/sqlx-data.json new file mode 100644 index 0000000..72c98b7 --- /dev/null +++ b/como_infrastructure/sqlx-data.json @@ -0,0 +1,346 @@ +{ + "db": "PostgreSQL", + "05d0a7901f0481d7443f125655df26eeacd63f2b023723a0c09c662617e0baf5": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + }, + { + "name": "title", + "ordinal": 1, + "type_info": "Varchar" + }, + { + "name": "description", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "state", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "project_id", + "ordinal": 4, + "type_info": "Uuid" + } + ], + "nullable": [ + false, + false, + true, + false, + false + ], + "parameters": { + "Left": [ + "Uuid", + "Text" + ] + } + }, + "query": "\n SELECT id, title, description, state, project_id\n FROM items\n WHERE id = $1 AND user_id = $2\n " + }, + "3b4484c5ccfd4dcb887c4e978fe6e45d4c9ecc2a73909be207dced79ddf17d87": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + } + ], + "nullable": [ + false + ], + "parameters": { + "Left": [ + "Varchar", + "Varchar" + ] + } + }, + "query": "\n INSERT INTO users (username, password_hash) \n VALUES ( $1, $2 ) \n RETURNING id\n " + }, + "4ec32ebd0ee991cec625d9de51de0d3e0ddfc8afda0568327fa9c818bde08e1f": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + } + ], + "nullable": [ + false + ], + "parameters": { + "Left": [ + "Uuid", + "Varchar", + "Varchar", + "Varchar", + "Timestamp", + "Timestamp" + ] + } + }, + "query": "\n INSERT INTO projects (id, name, description, user_id, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6)\n RETURNING id\n " + }, + "7901e81b1f1f08f0c7e72a967a8116efb62f40d99f80900f1e56cd13ad4f6bb2": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + }, + { + "name": "title", + "ordinal": 1, + "type_info": "Varchar" + }, + { + "name": "description", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "state", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "project_id", + "ordinal": 4, + "type_info": "Uuid" + } + ], + "nullable": [ + false, + false, + true, + false, + false + ], + "parameters": { + "Left": [ + "Uuid", + "Varchar", + "Varchar", + "Varchar", + "Uuid", + "Varchar" + ] + } + }, + "query": "\n INSERT INTO items (id, title, description, state, project_id, user_id, created_at, updated_at)\n VALUES ($1, $2, $3, $4, $5, $6, now(), now())\n RETURNING id, title, description, state, project_id\n " + }, + "a188dc748025cf3311820d16002b111a75f571d18f44f54b730ac14e9b2e10ea": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + }, + { + "name": "name", + "ordinal": 1, + "type_info": "Varchar" + }, + { + "name": "description", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "user_id", + "ordinal": 3, + "type_info": "Varchar" + } + ], + "nullable": [ + false, + false, + true, + false + ], + "parameters": { + "Left": [ + "Uuid", + "Text" + ] + } + }, + "query": "\n SELECT id, name, description, user_id\n FROM projects\n WHERE id = $1 and user_id = $2\n " + }, + "b930a7123d22d543e4d8ed70a1bc10477362127969ceca9653e445f26670003a": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + }, + { + "name": "name", + "ordinal": 1, + "type_info": "Varchar" + }, + { + "name": "description", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "user_id", + "ordinal": 3, + "type_info": "Varchar" + } + ], + "nullable": [ + false, + false, + true, + false + ], + "parameters": { + "Left": [ + "Text" + ] + } + }, + "query": "\n SELECT id, name, description, user_id\n FROM projects\n WHERE user_id = $1\n LIMIT 500\n " + }, + "bacf3c8a2f302d50991483fa36a06965c3536c2ef3837c19c6e6361eff312848": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + }, + { + "name": "title", + "ordinal": 1, + "type_info": "Varchar" + }, + { + "name": "description", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "state", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "project_id", + "ordinal": 4, + "type_info": "Uuid" + } + ], + "nullable": [ + false, + false, + true, + false, + false + ], + "parameters": { + "Left": [ + "Varchar", + "Varchar", + "Varchar", + "Uuid", + "Uuid", + "Text" + ] + } + }, + "query": "\n UPDATE items\n SET \n title = COALESCE($1, title), \n description = COALESCE($2, description), \n state = COALESCE($3, state), \n project_id = COALESCE($4, project_id), \n updated_at = now()\n WHERE id = $5 AND user_id = $6\n RETURNING id, title, description, state, project_id\n " + }, + "bd2407ffb9637afcff3ffe1101e7c1920b8cf0be423ab0313d14acc9c76e0f93": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + }, + { + "name": "title", + "ordinal": 1, + "type_info": "Varchar" + }, + { + "name": "description", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "state", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "project_id", + "ordinal": 4, + "type_info": "Uuid" + } + ], + "nullable": [ + false, + false, + true, + false, + false + ], + "parameters": { + "Left": [ + "Text", + "Uuid" + ] + } + }, + "query": "\n SELECT id, title, description, state, project_id\n FROM items\n WHERE user_id = $1 and project_id = $2\n LIMIT 500\n " + }, + "d3f222cf6c3d9816705426fdbed3b13cb575bb432eb1f33676c0b414e67aecaf": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Uuid" + }, + { + "name": "username", + "ordinal": 1, + "type_info": "Varchar" + }, + { + "name": "password_hash", + "ordinal": 2, + "type_info": "Varchar" + } + ], + "nullable": [ + false, + false, + false + ], + "parameters": { + "Left": [ + "Text" + ] + } + }, + "query": "\n SELECT * from users\n where username=$1\n " + } +} \ No newline at end of file diff --git a/como_infrastructure/src/services/item_service.rs b/como_infrastructure/src/services/item_service.rs index 11ec9b3..38e0a7c 100644 --- a/como_infrastructure/src/services/item_service.rs +++ b/como_infrastructure/src/services/item_service.rs @@ -1,24 +1,22 @@ -use std::{ - collections::HashMap, - sync::{Arc, Mutex}, -}; - +use crate::database::ConnectionPool; use async_trait::async_trait; use como_core::items::ItemService; use como_domain::{ item::{ queries::{GetItemQuery, GetItemsQuery}, - requests::CreateItemDto, + requests::{CreateItemDto, UpdateItemDto}, responses::CreatedItemDto, ItemDto, }, user::ContextUserExt, Context, }; +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, +}; use uuid::Uuid; -use crate::database::ConnectionPool; - pub struct DefaultItemService { pool: ConnectionPool, } @@ -48,7 +46,7 @@ impl ItemService for DefaultItemService { RETURNING id, title, description, state, project_id "#, Uuid::new_v4(), - item.name, + item.title, item.description, state, item.project_id, @@ -121,6 +119,41 @@ impl ItemService for DefaultItemService { }) .collect()) } + + async fn update_item(&self, context: &Context, item: UpdateItemDto) -> anyhow::Result { + let state = item.state.map(|s| serde_json::to_string(&s)).transpose()?; + let user_id = context.get_user_id().ok_or(anyhow::anyhow!("no user id"))?; + + let rec = sqlx::query!( + r#" + UPDATE items + SET + title = COALESCE($1, title), + description = COALESCE($2, description), + state = COALESCE($3, state), + project_id = COALESCE($4, project_id), + updated_at = now() + WHERE id = $5 AND user_id = $6 + RETURNING id, title, description, state, project_id + "#, + item.title, + item.description, + state, + item.project_id, + item.id, + user_id, + ) + .fetch_one(&self.pool) + .await?; + + Ok(ItemDto { + id: rec.id, + title: rec.title, + description: rec.description, + state: serde_json::from_str(&rec.state)?, + project_id: rec.project_id, + }) + } } pub struct MemoryItemService { @@ -145,7 +178,7 @@ impl ItemService for MemoryItemService { if let Ok(mut item_store) = self.item_store.lock() { let item = ItemDto { id: Uuid::new_v4(), - title: create_item.name, + title: create_item.title, description: create_item.description, state: como_domain::item::ItemState::Created, project_id: create_item.project_id, @@ -177,4 +210,8 @@ impl ItemService for MemoryItemService { ) -> anyhow::Result> { todo!() } + + async fn update_item(&self, context: &Context, item: UpdateItemDto) -> anyhow::Result { + todo!() + } } diff --git a/como_infrastructure/target/sqlx/como_infrastructure/query-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce.json b/como_infrastructure/target/sqlx/como_infrastructure/query-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce.json deleted file mode 100644 index 5fb3030..0000000 --- a/como_infrastructure/target/sqlx/como_infrastructure/query-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "query": "\n SELECT id, title, description, state, project_id\n FROM items\n WHERE user_id = $1 and project_id = $2\n LIMIT 500\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Uuid" - }, - { - "ordinal": 1, - "name": "title", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "description", - "type_info": "Varchar" - }, - { - "ordinal": 3, - "name": "state", - "type_info": "Varchar" - }, - { - "ordinal": 4, - "name": "project_id", - "type_info": "Uuid" - } - ], - "parameters": { - "Left": [ - "Text", - "Uuid" - ] - }, - "nullable": [ - false, - false, - true, - false, - false - ] - }, - "hash": "bd2407ffb9637afcff3ffe1101e7c1920b8cf0be423ab0313d14acc9c76e0f93" -} \ No newline at end of file diff --git a/como_infrastructure/target/sqlx/query-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce.json b/como_infrastructure/target/sqlx/query-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce.json deleted file mode 100644 index c881b13..0000000 --- a/como_infrastructure/target/sqlx/query-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "query": "\n SELECT * from users\n where username=$1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Uuid" - }, - { - "ordinal": 1, - "name": "username", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "password_hash", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "d3f222cf6c3d9816705426fdbed3b13cb575bb432eb1f33676c0b414e67aecaf" -} \ No newline at end of file diff --git a/cuddle.yaml b/cuddle.yaml index 047330e..34cec2a 100644 --- a/cuddle.yaml +++ b/cuddle.yaml @@ -4,7 +4,8 @@ base: "git@git.front.kjuulh.io:kjuulh/cuddle-rust-plan.git" vars: service: "como-backend" - deployments: "git@git.front.kjuulh.io:como/deployments.git" + deployments: "git@git.front.kjuulh.io:kjuulh/como-deployments.git" + bin_name: como_bin scripts: render_como_templates: @@ -23,4 +24,5 @@ scripts: name: type: "env" key: "name" - + "sqlx:prepare": + type: shell diff --git a/rust-toolchain.toml b/rust-toolchain.toml deleted file mode 100644 index 5d56faf..0000000 --- a/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -channel = "nightly" diff --git a/scripts/sqlx:prepare.sh b/scripts/sqlx:prepare.sh new file mode 100755 index 0000000..e97612a --- /dev/null +++ b/scripts/sqlx:prepare.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +export $(cat .env | xargs) + +cd como_infrastructure || return + +cargo sqlx prepare -- --all-targets --all-features diff --git a/templates/init-user-db.sh b/templates/init-user-db.sh index e83e492..8ee663b 100644 --- a/templates/init-user-db.sh +++ b/templates/init-user-db.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!bin/bash set -e psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL