Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/publish-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,5 @@ jobs:
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
async-graphql = { version = "7.0.16", features = ["bson", "chrono", "uuid", "log"] }
async-graphql-axum = "7.0.16"
async-graphql = { version = "7.0.17", features = ["bson", "chrono", "uuid", "log"] }
async-graphql-axum = "7.0.17"
tokio = { version = "1.44.2", features = ["macros", "rt-multi-thread"] }
hyper = "1.0.1"
axum = { version = "0.8.3", features = ["macros"] }
Expand All @@ -19,7 +19,7 @@ clap = { version = "4.5.37", features = ["derive"] }
uuid = { version = "1.16.0", features = ["v4", "serde"] }
json = "0.12.4"
log = "0.4.27"
simple_logger = "5.0.0"
env_logger = "0.11"
serde_json = "1.0.140"
reqwest = { version = "0.12.15", features = ["json"] }
chrono = { version = "0.4.40", features = ["serde"] }
Expand Down
25 changes: 19 additions & 6 deletions src/event/http_event_service.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use async_graphql::Result;
use axum::{debug_handler, extract::State, http::StatusCode, Json};
use bson::{doc, Uuid};
use log::info;
use log::{error, info};
use mongodb::{options::UpdateOptions, Collection};
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -42,6 +42,7 @@ pub struct Event<T> {
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
/// Relevant part of vendor address creation event.
pub struct VendorAddressEventData {
/// Vendor address UUID.
Expand All @@ -61,6 +62,7 @@ pub struct VendorAddressEventData {
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
/// Relevant part of user creation event data.
pub struct UserEventData {
/// User UUID.
Expand Down Expand Up @@ -199,7 +201,7 @@ pub async fn list_topic_subscriptions() -> Result<Json<Vec<Pubsub>>, StatusCode>
let pubsub_user = Pubsub {
pubsubname: "pubsub".to_string(),
topic: "user/user/created".to_string(),
route: "/on-id-creation-event".to_string(),
route: "/on-user-creation-event".to_string(),
};
let pubsub_user_address = Pubsub {
pubsubname: "pubsub".to_string(),
Expand Down Expand Up @@ -235,7 +237,10 @@ pub async fn on_discount_order_validation_succeeded_event(
"discount/order/validation-succeeded" => {
let invoice = Invoice::new(event.data.order.clone(), &state)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
.map_err(|e| {
error!("Failed to create invoice: {:?}", e);
StatusCode::INTERNAL_SERVER_ERROR
})?;
let invoice_dto = InvoiceDTO::from(invoice.clone());
let invoice_created_dto = InvoiceCreatedDTO::from((event.data.order, invoice_dto));
insert_invoice_in_mongodb(&state.invoice_collection, invoice).await?;
Expand Down Expand Up @@ -374,7 +379,15 @@ pub async fn create_or_update_vendor_address_in_mongodb(
match collection
.update_one(
doc! {"_id": vendor_address._id },
doc! {"$set": {"_id": vendor_address._id}},
doc! {"$set": {
"_id": vendor_address._id,
"street1": vendor_address.street1,
"street2": vendor_address.street2,
"city": vendor_address.city,
"postal_code": vendor_address.postal_code,
"country": vendor_address.country,
"company_name": vendor_address.company_name,
}},
update_options,
)
.await
Expand All @@ -395,7 +408,7 @@ pub async fn insert_user_address_in_mongodb(
match collection
.update_one(
doc! {"_id": user_address.user_id },
doc! {"$push": {"user_addresses": user_address }},
doc! {"$push": {"addresses": user_address }},
None,
)
.await
Expand All @@ -416,7 +429,7 @@ pub async fn remove_user_address_in_mongodb(
match collection
.update_one(
doc! {"_id": user_address_event_data.user_id },
doc! {"$pull": {"user_addresses._id": user_address_event_data.id }},
doc! {"$pull": {"addresses._id": user_address_event_data.id }},
None,
)
.await
Expand Down
19 changes: 14 additions & 5 deletions src/graphql/model/invoice.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use async_graphql::{Error, Result, SimpleObject};
use bson::{doc, DateTime, Uuid};
use log::error;
use mongodb::{options::FindOneOptions, Collection};
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -122,10 +123,16 @@ async fn invoice_attribute_setup(
let order_item_invoice_overview = build_order_item_invoice_content(order_event_data);
let user_address_user =
query_user_address_user(&state.user_collection, order_event_data.invoice_address_id)
.await?;
let user_address = project_user_to_user_address(user_address_user)?;
let vendor_address = query_vendor_address(&state.vendor_address_collection).await?;
let user = query_object(&state.user_collection, order_event_data.user_id).await?;
.await
.map_err(|e| { error!("step 1 query_user_address_user: {:?}", e); e })?;
let user_address = project_user_to_user_address(user_address_user)
.map_err(|e| { error!("step 2 project_user_to_user_address: {:?}", e); e })?;
let vendor_address = query_vendor_address(&state.vendor_address_collection)
.await
.map_err(|e| { error!("step 3 query_vendor_address: {:?}", e); e })?;
let user = query_object(&state.user_collection, order_event_data.user_id)
.await
.map_err(|e| { error!("step 4 query_object user: {:?}", e); e })?;
Ok((
issued_at,
issued_at_string,
Expand Down Expand Up @@ -159,7 +166,9 @@ pub async fn query_user_address_user(
let find_options = FindOneOptions::builder()
.projection(Some(doc! {
"addresses.$": 1,
"_id": 1
"_id": 1,
"first_name": 1,
"last_name": 1,
}))
.build();
let message = format!("Address of UUID: `{}` not found.", address_id);
Expand Down
2 changes: 2 additions & 0 deletions src/graphql/model/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct Order {

/// Describes if order is placed, or yet pending. An order can be rejected during its lifetime.
#[derive(Debug, Enum, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum OrderStatus {
Pending,
Placed,
Expand All @@ -23,6 +24,7 @@ pub enum OrderStatus {

/// Describes the reason why an order was rejected, in case of rejection: `OrderStatus::Rejected`.
#[derive(Debug, Enum, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum RejectionReason {
InvalidOrderData,
InventoryReservationFailed,
Expand Down
5 changes: 3 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use axum::{
};
use clap::{arg, command, Parser};

use log::{info, Level};
use log::info;
use mongodb::{options::ClientOptions, Client, Database};

use once_cell::sync::Lazy;
Expand Down Expand Up @@ -113,7 +113,8 @@ struct Args {
/// Activates logger and parses argument for optional schema generation. Otherwise starts gRPC and GraphQL server.
#[tokio::main]
async fn main() -> std::io::Result<()> {
simple_logger::init_with_level(Level::Warn).unwrap();
env_logger::init();
info!("Invoice service starting");

let args = Args::parse();
if args.generate_schema {
Expand Down