Add some docs, stock methods

This commit is contained in:
Adrian Woźniak 2022-11-07 16:28:51 +01:00
parent 27dfa5444e
commit a3dd9b85d8
No known key found for this signature in database
GPG Key ID: 0012845A89C7352B
16 changed files with 861 additions and 178 deletions

View File

@ -206,10 +206,60 @@ pub mod create_index {
} }
} }
pub mod delete_index {
use crate::search::Error;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub key: String,
pub value: String,
pub bucket: String,
pub collection: String,
}
impl Input {
pub fn new<K: Into<String>, V: Into<String>, B: Into<String>, C: Into<String>>(
key: K,
value: V,
collection: C,
bucket: B,
) -> Self {
Self {
key: key.into(),
value: value.into(),
bucket: bucket.into(),
collection: collection.into(),
}
}
}
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub found: Option<()>,
pub error: Option<Error>,
}
impl Output {
pub fn ok() -> Self {
Self {
found: Some(()),
..Default::default()
}
}
pub fn error(error: Error) -> Self {
Self {
error: Some(error),
..Default::default()
}
}
}
}
pub mod rpc { pub mod rpc {
use config::SharedAppConfig; use config::SharedAppConfig;
use crate::search::{create_index, search, suggest}; use crate::search::{create_index, delete_index, search, suggest};
#[tarpc::service] #[tarpc::service]
pub trait Search { pub trait Search {
@ -221,6 +271,9 @@ pub mod rpc {
/// Create new search index. /// Create new search index.
async fn create_index(input: create_index::Input) -> create_index::Output; async fn create_index(input: create_index::Input) -> create_index::Output;
/// Delete search index.
async fn delete_index(input: delete_index::Input) -> delete_index::Output;
} }
pub async fn create_client(config: SharedAppConfig) -> SearchClient { pub async fn create_client(config: SharedAppConfig) -> SearchClient {

View File

@ -1,100 +0,0 @@
pub static CLIENT_NAME: &str = "stocks";
pub mod create_product {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct ProductInput {
pub name: ProductName,
pub short_description: ProductShortDesc,
pub long_description: ProductLongDesc,
pub category: Option<ProductCategory>,
pub price: Price,
pub deliver_days_flag: Days,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct StockInput {
pub quantity: Quantity,
pub quantity_unit: QuantityUnit,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub product: ProductInput,
pub stock: StockInput,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product: model::Product,
pub stocks: Vec<model::Stock>,
pub photos: Vec<model::Photo>,
}
}
pub mod detailed_product {
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub product_id: model::ProductId,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product: model::Product,
pub stocks: Vec<model::Stock>,
pub photos: Vec<model::Photo>,
}
}
pub mod detailed_products {
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub products: Vec<model::DetailedProduct>,
}
}
pub mod rpc {
use config::SharedAppConfig;
use crate::accounts::register;
#[tarpc::service]
pub trait Stocks {
/// List of products with stock size and photos
async fn detailed_products(input: register::Input) -> register::Output;
}
pub async fn create_client(config: SharedAppConfig) -> StocksClient {
use tarpc::client;
use tarpc::tokio_serde::formats::Bincode;
let l = config.lock();
let addr = l.stocks_manager().rpc_addr();
let transport = tarpc::serde_transport::tcp::connect(addr, Bincode::default);
let client = StocksClient::new(
client::Config::default(),
transport.await.expect("Failed to connect to server"),
)
.spawn();
client
}
}
pub mod mqtt {
use config::SharedAppConfig;
use rumqttc::EventLoop;
use crate::stocks::CLIENT_NAME;
use crate::AsyncClient;
pub fn create_client(config: SharedAppConfig) -> (AsyncClient, EventLoop) {
crate::mqtt::create_client(CLIENT_NAME, config.lock().stocks_manager().mqtt_addr())
}
}

View File

@ -0,0 +1,27 @@
pub mod detailed_product {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub product_id: ProductId,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product: model::Product,
pub stocks: Vec<Stock>,
pub photos: Vec<Photo>,
}
}
pub mod detailed_products {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub products: Vec<DetailedProduct>,
}
}

View File

@ -0,0 +1,103 @@
pub mod load;
pub mod product;
pub mod product_photo;
pub mod product_stock;
pub mod product_variant;
pub use load::*;
pub use product::*;
pub use product_photo::*;
pub use product_stock::*;
pub use product_variant::*;
pub static CLIENT_NAME: &str = "stocks";
pub mod rpc {
use config::SharedAppConfig;
use crate::stocks::load::*;
use crate::stocks::product::*;
use crate::stocks::product_photo::*;
use crate::stocks::product_stock::*;
use crate::stocks::product_variant::*;
#[tarpc::service]
pub trait Stocks {
// Product
/// Create new product.
async fn create_product(input: create_product::Input) -> create_product::Output;
/// Update product information.
async fn update_product(input: update_product::Input) -> update_product::Output;
/// Delete product.
async fn delete_product(input: delete_product::Input) -> delete_product::Output;
// Product variant
/// Create new variant of the product.
async fn create_product_variant(
input: create_product_variant::Input,
) -> create_product_variant::Output;
/// Update variant of the product.
async fn update_product_variant(
input: update_product_variant::Input,
) -> update_product_variant::Output;
/// Delete variant from the product.
async fn delete_product_variant(
input: delete_product_variant::Input,
) -> delete_product_variant::Output;
// Product photo
/// Add new photo to product.
async fn add_product_photo(input: add_product_photo::Input) -> add_product_photo::Output;
/// Add delete photo from product.
async fn delete_product_photo(
input: delete_product_photo::Input,
) -> delete_product_photo::Output;
// Product stock
/// Create product stock.
async fn create_product_stock(
input: create_product_stock::Input,
) -> create_product_stock::Output;
/// Update product stock.
async fn update_product_stock(
input: update_product_stock::Input,
) -> update_product_stock::Output;
// Load
/// Single product with stock size and photos
async fn detailed_product(input: detailed_product::Input) -> detailed_product::Output;
/// List of products with stock size and photos
async fn detailed_products(input: detailed_products::Input) -> detailed_products::Output;
}
pub async fn create_client(config: SharedAppConfig) -> StocksClient {
use tarpc::client;
use tarpc::tokio_serde::formats::Bincode;
let l = config.lock();
let addr = l.stocks_manager().rpc_addr();
let transport = tarpc::serde_transport::tcp::connect(addr, Bincode::default);
let client = StocksClient::new(
client::Config::default(),
transport.await.expect("Failed to connect to server"),
)
.spawn();
client
}
}
pub mod mqtt {
use config::SharedAppConfig;
use rumqttc::EventLoop;
use crate::stocks::CLIENT_NAME;
use crate::AsyncClient;
pub fn create_client(config: SharedAppConfig) -> (AsyncClient, EventLoop) {
crate::mqtt::create_client(CLIENT_NAME, config.lock().stocks_manager().mqtt_addr())
}
}

View File

@ -0,0 +1,63 @@
pub mod create_product {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct ProductInput {
pub name: ProductName,
pub variant_name: Option<ProductVariantName>,
pub short_description: ProductShortDesc,
pub long_description: ProductLongDesc,
pub category: Option<ProductCategory>,
pub price: Price,
pub deliver_days_flag: Days,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct StockInput {
pub quantity: Quantity,
pub quantity_unit: QuantityUnit,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub product: ProductInput,
pub stock: StockInput,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product: model::Product,
pub stocks: Vec<Stock>,
pub photos: Vec<Photo>,
}
}
pub mod update_product {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub name: ProductName,
pub category: Option<ProductCategory>,
pub deliver_days_flag: Days,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product: model::Product,
}
}
pub mod delete_product {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub product_id: ProductId,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product_id: ProductId,
}
}

View File

@ -0,0 +1,35 @@
pub mod add_product_photo {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub local_path: LocalPath,
pub file_name: FileName,
pub unique_name: UniqueName,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub photo_id: ProductPhotoId,
pub product_variant_id: ProductVariantId,
pub local_path: LocalPath,
pub file_name: FileName,
pub unique_name: UniqueName,
}
}
pub mod delete_product_photo {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub photo_id: ProductPhotoId,
pub product_variant_id: ProductVariantId,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub photo_id: ProductPhotoId,
pub product_variant_id: ProductVariantId,
}
}

View File

@ -0,0 +1,32 @@
pub mod create_product_stock {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub product_variant_id: ProductVariantId,
pub quantity: Quantity,
pub quantity_unit: QuantityUnit,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product_stock: Stock,
}
}
pub mod update_product_stock {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub id: StockId,
pub product_variant_id: ProductVariantId,
pub quantity: Quantity,
pub quantity_unit: QuantityUnit,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product_stock: Stock,
}
}

View File

@ -0,0 +1,52 @@
pub mod create_product_variant {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub product_id: ProductId,
pub name: ProductName,
pub short_description: ProductShortDesc,
pub long_description: ProductLongDesc,
pub price: Price,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product_variant: ProductVariant,
}
}
pub mod update_product_variant {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub id: ProductVariantId,
pub product_id: ProductId,
pub name: ProductName,
pub short_description: ProductShortDesc,
pub long_description: ProductLongDesc,
pub price: Price,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product_variant: ProductVariant,
}
}
pub mod delete_product_variant {
use model::v2::*;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Input {
pub product_id: ProductId,
pub product_variant_id: ProductVariantId,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Output {
pub product_id: ProductId,
pub product_variant_id: ProductVariantId,
}
}

View File

@ -834,7 +834,7 @@ impl ProductName {
self.0 self.0
} }
pub fn as_sr(&self) -> &str { pub fn as_str(&self) -> &str {
&self.0 &self.0
} }
} }
@ -854,7 +854,7 @@ impl ProductShortDesc {
self.0 self.0
} }
pub fn as_sr(&self) -> &str { pub fn as_str(&self) -> &str {
&self.0 &self.0
} }
} }
@ -870,7 +870,7 @@ impl ProductLongDesc {
self.0 self.0
} }
pub fn as_sr(&self) -> &str { pub fn as_str(&self) -> &str {
&self.0 &self.0
} }
} }
@ -893,18 +893,41 @@ impl ProductCategory {
Self(s.into()) Self(s.into())
} }
pub fn as_sr(&self) -> &str { pub fn as_str(&self) -> &str {
&self.0 &self.0
} }
} }
pub mod v2 { pub mod v2 {
use derive_more::{Deref, Display, From};
use serde::{Deserialize, Serialize};
pub use crate::{ pub use crate::{
Days, FileName, LocalPath, PhotoId, Price, ProductCategory, ProductId, ProductLongDesc, Days, FileName, LocalPath, PhotoId, Price, ProductCategory, ProductId, ProductLongDesc,
ProductName, ProductPhotoId, ProductShortDesc, Quantity, QuantityUnit, RecordId, StockId, ProductName, ProductPhotoId, ProductShortDesc, Quantity, QuantityUnit, RecordId, StockId,
UniqueName, UniqueName,
}; };
#[cfg_attr(feature = "db", derive(sqlx::Type))]
#[cfg_attr(feature = "db", sqlx(transparent))]
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Deref, Display, From)]
#[serde(transparent)]
pub struct ProductVariantName(String);
impl ProductVariantName {
pub fn new<S: Into<String>>(s: S) -> Self {
Self(s.into())
}
pub fn into_inner(self) -> String {
self.0
}
pub fn as_str(&self) -> &str {
&self.0
}
}
#[cfg_attr(feature = "dummy", derive(fake::Dummy))] #[cfg_attr(feature = "dummy", derive(fake::Dummy))]
#[cfg_attr(feature = "db", derive(sqlx::Type))] #[cfg_attr(feature = "db", derive(sqlx::Type))]
#[cfg_attr(feature = "db", sqlx(transparent))] #[cfg_attr(feature = "db", sqlx(transparent))]
@ -942,6 +965,7 @@ pub mod v2 {
#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProductVariant { pub struct ProductVariant {
pub id: ProductVariantId, pub id: ProductVariantId,
pub product_id: ProductId,
pub name: ProductName, pub name: ProductName,
pub short_description: ProductShortDesc, pub short_description: ProductShortDesc,
pub long_description: ProductLongDesc, pub long_description: ProductLongDesc,

View File

@ -1,6 +1,6 @@
use channels::search::{create_index, search, suggest, Error}; use channels::search::{create_index, delete_index, search, suggest, Error};
use config::SharedAppConfig; use config::SharedAppConfig;
use sonic_channel::{Dest, ObjDest, PushRequest, QueryRequest, SuggestRequest}; use sonic_channel::{Dest, ObjDest, PopRequest, PushRequest, QueryRequest, SuggestRequest};
use crate::context::Context; use crate::context::Context;
@ -73,6 +73,27 @@ pub async fn create_index(
} }
} }
pub async fn delete_index(
msg: delete_index::Input,
ctx: Context,
_config: SharedAppConfig,
) -> delete_index::Output {
if let Ok(l) = ctx.ingest.lock() {
match l.pop(PopRequest::new(
ObjDest::new(Dest::col_buc(msg.collection, msg.bucket), &msg.key),
&msg.value,
)) {
Ok(_) => delete_index::Output::ok(),
Err(e) => {
tracing::error!("pop {e:?}");
delete_index::Output::error(Error::CantCreate)
}
}
} else {
delete_index::Output::ok()
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use channels::Lang; use channels::Lang;

View File

@ -1,5 +1,5 @@
use channels::search::rpc::Search; use channels::search::rpc::Search;
use channels::search::{create_index, search, suggest}; use channels::search::{create_index, delete_index, search, suggest};
use config::SharedAppConfig; use config::SharedAppConfig;
use tarpc::context; use tarpc::context;
@ -31,6 +31,15 @@ impl Search for SearchServer {
tracing::info!("Received {:?}", input); tracing::info!("Received {:?}", input);
crate::actions::create_index(input, self.ctx, self.config).await crate::actions::create_index(input, self.ctx, self.config).await
} }
async fn delete_index(
self,
_: context::Context,
input: delete_index::Input,
) -> delete_index::Output {
tracing::info!("Received {:?}", input);
crate::actions::delete_index(input, self.ctx, self.config).await
}
} }
pub async fn start(config: SharedAppConfig, ctx: Context) { pub async fn start(config: SharedAppConfig, ctx: Context) {

View File

@ -3,9 +3,17 @@
'scale 600 width 'scale 600 width
[*] --> CreateProduct [*] --> CreateProduct
[*] --> LoadAllProducts [*] --> UpdateProduct
[*] --> LoadDetailedProducts
state Product {
state CreateProduct {
state "Received create Product " as HttpCreateProduct
state "Call RPC Create Product" as CallRpcCreateProduct
state "Insert record in database" as InsertRecord
state "Returns created product via RPC" as RpcReturnDetailedProduct
state "Emit product_created via MQTT" as ProductCreatedEvent
state CreateProduct {
HttpCreateProduct --> CallRpcCreateProduct : RPC HttpCreateProduct --> CallRpcCreateProduct : RPC
CallRpcCreateProduct --> InsertRecord CallRpcCreateProduct --> InsertRecord
@ -14,15 +22,40 @@ state CreateProduct {
RpcReturnDetailedProduct --> [*] RpcReturnDetailedProduct --> [*]
ProductCreatedEvent --> [*] ProductCreatedEvent --> [*]
}
'state "Update product" as UpdateProduct
state UpdateProduct {
state "Received Update product via HTTP" as HttpUpdateProduct
state "Call RPC Update Product" as CallRpcUpdateProduct
state "Update Single Product" as UpdateSingleProduct
state "Returns updated product via RPC" as RpcReturnsUpdatedProduct
state "Returns failed to update product via RPC" as RpcReturnsFailedUpdateProduct
state "Emit product_updated via MQTT" as ProductUpdatedEvent
HttpUpdateProduct --> CallRpcUpdateProduct : RPC
CallRpcUpdateProduct --> UpdateSingleProduct
UpdateSingleProduct --> RpcReturnsUpdatedProduct
UpdateSingleProduct --> RpcReturnsFailedUpdateProduct
UpdateSingleProduct --> ProductUpdatedEvent
RpcReturnsUpdatedProduct --> [*] : Succeeded
RpcReturnsFailedUpdateProduct --> [*] : Failed
ProductUpdatedEvent --> [*] : Succeeded
}
} }
state LoadAllProducts { state LoadDetailedProducts {
state "Received Load all HTTP Request" as HttpLoadAll state "Received Load all HTTP Request" as HttpLoadAll
state "Call RPC Load All" as CallRpcLoadAll state "Call RPC Load All" as CallRpcLoadAll
state "Load add required data from DB" as LoadAllData state "Load add required data from DB" as LoadAllData
state "Load all products" as LoadProducts state "Load all products" as LoadProducts
state "Load all variants for all products" as LoadProductsVariants state "Load all variants for all products" as LoadProductsVariants
state "Load all products photos" as LoadProductsPhotos state "Load all products photos" as LoadProductsPhotos
state "Combine all data" as CombineData
state "Returns list via RPC" as RpcReturnsList
HttpLoadAll --> CallRpcLoadAll : RPC HttpLoadAll --> CallRpcLoadAll : RPC
CallRpcLoadAll --> LoadAllData CallRpcLoadAll --> LoadAllData

View File

@ -0,0 +1,15 @@
@startuml
'https://plantuml.com/sequence-diagram
autonumber
Http -> RPC : Call RPC Create product
RPC -> PostgreSQL : Create record
alt Success case
Http <- RPC : Product created
MQTT <- RPC : Emit product_created event
else Failed
Http <- RPC : Create failed
end
@enduml

View File

@ -0,0 +1,15 @@
@startuml
'https://plantuml.com/sequence-diagram
autonumber
Http -> RPC : Call RPC Update product
RPC -> PostgreSQL : Update record
alt Success case
Http <- RPC : Product updated
MQTT <- RPC : Emit product_updated event
else Failed
Http <- RPC : Updated failed
end
@enduml

52
docs/dependencies.puml Normal file
View File

@ -0,0 +1,52 @@
@startuml
'https://plantuml.com/deployment-diagram
rectangle "Dependencies" {
database bazzar_accounts2 [
PostgreSQL
---
bazzar_accounts
]
database bazzar_carts2 [
PostgreSQL
---
bazzar_carts
]
database "sonic "
database bazzar_stocks2 [
PostgreSQL
---
bazzar_stocks
]
cloud "sendgrid "
queue "rumqttd "
}
'actor actor
'actor/ "actor/"
'agent agent
'artifact artifact
'boundary boundary
'card card
'circle circle
'cloud cloud
'collections collections
'component component
'control control
'database database
'entity entity
'file file
'folder folder
'frame frame
'interface interface
'label label
'node node
'package package
'queue queue
'rectangle rectangle
'stack stack
'storage storage
'usecase usecase
'usecase/ "usecase/"
@enduml

View File

@ -4,100 +4,349 @@
scale 1000 scale 1000
rectangle "API" { rectangle "API" {
' left to right direction
node "bazzar" node "bazzar"
queue rumqttd queue rumqttd
component "Accounts Manager" { component "Accounts" {
node "account-manager" node "account-manager"
database "PostgreSQL bazzar_accounts" database bazzar_accounts [
PostgreSQL
---
bazzar_accounts
]
"account-manager" <--> "PostgreSQL bazzar_accounts" "account-manager" <-up-> bazzar_accounts
"account-manager" --> rumqttd : emit event "account-manager" --> rumqttd : emit event
usecase "create account" usecase create_account [
usecase "me" Create
account
]
usecase me [
Me
]
usecase load_public_info [
Load
public
info
]
usecase delete_account [
Delete
account
]
usecase update_account [
Update
account
]
"account-manager" -- "create account" "account-manager" -- create_account
"account-manager" -- "me" "account-manager" -- me
"account-manager" -- load_public_info
"account-manager" -- delete_account
"account-manager" -- update_account
} }
component "Carts Manager" { component "Carts" {
node "cart-manager" node "cart-manager"
database "PostgreSQL bazzar_carts" database bazzar_carts [
PostgreSQL
---
bazzar_carts
]
"cart-manager" <--> "PostgreSQL bazzar_carts" "cart-manager" <-up-> bazzar_carts
"cart-manager" <-- rumqttd : account created
usecase modify_item [
Modify
item
]
usecase remove_product [
Remove
product
]
usecase modify_cart [
Modify
cart
]
usecase active_shopping_cart [
Active
shopping
cart
]
active_shopping_cart <-- rumqttd : account created
remove_product <-- rumqttd : product deleted
"cart-manager" -- modify_item
"cart-manager" -- remove_product
"cart-manager" -- modify_cart
"cart-manager" -- active_shopping_cart
} }
component "Search Manager" { component "Search" {
node "search-manager" node "search-manager"
database "sonic" database "sonic"
"search-manager" <--> "sonic" "search-manager" <-up-> "sonic"
"search-manager" <-- rumqttd : product created
"search-manager" <-- rumqttd : product deleted usecase suggest [
Suggest
]
usecase search [
Search
]
usecase create_index [
Create
index
]
usecase delete_index [
Delete
index
]
create_index <-- rumqttd : product created
delete_index <-- rumqttd : product deleted
"search-manager" -- suggest
"search-manager" -- search
"search-manager" -- create_index
"search-manager" -- delete_index
} }
component "Stock Manager" { component "Stocks" {
node "stock-manager" node "stock-manager"
database "PostgreSQL bazzar_stocks" database bazzar_stocks [
PostgreSQL
---
bazzar_stocks
]
"stock-manager" <--> "PostgreSQL bazzar_stocks" "stock-manager" <-up-> bazzar_stocks
"stock-manager" --> rumqttd : emit event "stock-manager" --> rumqttd : emit event
circle product [
Product
]
usecase create_product [
Create
product
]
usecase update_product [
Update
product
]
usecase delete_product [
Delete
product
]
circle product_variant [
Product
variant
]
usecase add_product_variant [
Add
product
variant
]
usecase update_product_variant [
Update
product
variant
]
usecase delete_product_variant [
Delete
product
variant
]
circle product_photo [
Product
photo
]
usecase add_product_photo [
Add
product
photo
]
usecase remove_product_photo [
Remove
product
photo
]
circle product_stock [
Product
stock
]
usecase update_product_stock [
Update
product
stock
]
usecase load_detailed_products [
Load
detailed
products
]
usecase load_single_product [
Load
single
product
]
"stock-manager" -- product
product -- create_product
product -- update_product
product -- delete_product
"stock-manager" -- product_variant
product_variant -- add_product_variant
product_variant -- update_product_variant
product_variant -- delete_product_variant
"stock-manager" -- product_photo
product_photo -- add_product_photo
product_photo -- remove_product_photo
"stock-manager" -- product_stock
product_stock -- update_product_stock
"stock-manager" -- load_detailed_products
"stock-manager" -- load_single_product
} }
component "E-Mail Sender" { component "E-Mail Sender" {
node "email-sender" node "email-sender"
cloud "sendgrid" cloud "sendgrid"
"email-sender" --> "sendgrid" "email-sender" -up-> "sendgrid"
"email-sender" <-- rumqttd : account created
"email-sender" <-- rumqttd : account deleted usecase welcome [
Welcome
]
usecase reset_password [
Reset
password
]
usecase goodbye [
Reset
password
]
welcome <-- rumqttd : account created
goodbye <-- rumqttd : account deleted
"email-sender" -- welcome
"email-sender" -- reset_password
"email-sender" -- goodbye
} }
component "Payments" {
node "payment-manager"
cloud payment_service [
Payment
cloud
service
]
database bazzar_payments [
PostgreSQL
---
bazzar_payments
]
"payment-manager" <-up(0)-> payment_service : http
"payment-manager" <-up-> bazzar_payments
"payment-manager" --> rumqttd : emit event
usecase request [
Request
payment
]
usecase update_state [
Update
payment
state
]
"payment-manager" -- request
"payment-manager" -- update_state
}
component "Orders" {
node "order-manager"
database bazzar_orders [
PostgreSQL
---
bazzar_orders
]
"order-manager" <-up-> bazzar_orders
"order-manager" --> rumqttd : emit event
usecase create_order [
Create
order
]
usecase update_order_state [
Update
order
state
]
update_order_state <-- rumqttd : payment_status_changed
usecase cancel_order [
Cancel
order
]
"order-manager" -- create_order
"order-manager" -- update_order_state
"order-manager" -- cancel_order
}
component "Tokens" {
node "token-manager"
database bazzar_tokens [
PostgreSQL
---
bazzar_tokens
]
"token-manager" <-up-> bazzar_tokens
"token-manager" --> rumqttd : emit event
usecase create_jwt [
Create
JWT
]
usecase validate_jwt [
Validate
JWT
]
usecase refresh_jwt [
Refresh
JWT
]
"token-manager" -- create_jwt
"token-manager" -- validate_jwt
"token-manager" -- refresh_jwt
}
rectangle {
actor " rumqttd" actor " rumqttd"
"bazzar" -- "Accounts Manager" : rpc "bazzar" -- "Accounts" : rpc
"bazzar" -- "Carts Manager" : rpc "bazzar" -- "Carts" : rpc
"bazzar" -- "E-Mail Manager" : rpc "bazzar" -- "Stocks" : rpc
"bazzar" -- "Search" : rpc
"bazzar" -- "E-Mail" : rpc
"bazzar" -- "Tokens" : rpc
"bazzar" -- "Payments" : rpc
"bazzar" --> " rumqttd" : emit event "bazzar" --> " rumqttd" : emit event
}
rectangle "Dependencies" {
database "PostgreSQL bazzar_accounts "
database "PostgreSQL bazzar_carts "
database "sonic "
database "PostgreSQL bazzar_stocks " {
} }
cloud "sendgrid "
queue "rumqtt d"
} }
'actor actor
'actor/ "actor/"
'agent agent
'artifact artifact
'boundary boundary
'card card
'circle circle
'cloud cloud
'collections collections
'component component
'control control
'database database
'entity entity
'file file
'folder folder
'frame frame
'interface interface
'label label
'node node
'package package
'queue queue
'rectangle rectangle
'stack stack
'storage storage
'usecase usecase
'usecase/ "usecase/"
@enduml @enduml