feat: bootstrap inventory web adapter
This commit is contained in:
parent
12c386ec8c
commit
8ad620476d
7 changed files with 193 additions and 3 deletions
|
@ -1,3 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
pub mod web;
|
||||||
|
|
16
src/inventory/adapters/input/web/category.rs
Normal file
16
src/inventory/adapters/input/web/category.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
use actix_identity::Identity;
|
||||||
|
use actix_web::{get, http::header::ContentType, post, web, HttpRequest, HttpResponse, Responder};
|
||||||
|
use derive_builder::Builder;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use url::Url;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use super::errors::*;
|
||||||
|
use super::types;
|
||||||
|
//use crate::utils::uuid::WebGetUUIDInterfaceObj;
|
||||||
|
|
||||||
|
pub fn services(cfg: &mut web::ServiceConfig) {}
|
110
src/inventory/adapters/input/web/errors.rs
Normal file
110
src/inventory/adapters/input/web/errors.rs
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
use actix_web::http::StatusCode;
|
||||||
|
use actix_web::{HttpResponse, ResponseError};
|
||||||
|
use derive_more::Display;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::inventory::application::services::errors::*;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
|
||||||
|
struct ErrorResponse {
|
||||||
|
error: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WebError> for ErrorResponse {
|
||||||
|
fn from(value: WebError) -> Self {
|
||||||
|
ErrorResponse {
|
||||||
|
error: serde_json::to_string(&value).unwrap_or_else(|_| {
|
||||||
|
log::error!("Unable to serialize error");
|
||||||
|
"Unable to serialize error".into()
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Display, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum WebError {
|
||||||
|
InternalError,
|
||||||
|
BadRequest,
|
||||||
|
|
||||||
|
DuplicateCategoryName,
|
||||||
|
DuplicateStoreName,
|
||||||
|
DuplicateProductName,
|
||||||
|
DuplicateCustomizationName,
|
||||||
|
DuplicateCustomizationID,
|
||||||
|
DuplicateStoreID,
|
||||||
|
DuplicateCategoryID,
|
||||||
|
DuplicateProductID,
|
||||||
|
ProductIDNotFound,
|
||||||
|
CategoryIDNotFound,
|
||||||
|
CustomizationIDNotFound,
|
||||||
|
StoreIDNotFound,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<InventoryError> for WebError {
|
||||||
|
fn from(v: InventoryError) -> Self {
|
||||||
|
match v {
|
||||||
|
InventoryError::InternalError => Self::InternalError,
|
||||||
|
InventoryError::DuplicateCategoryName => Self::BadRequest,
|
||||||
|
InventoryError::DuplicateStoreName => Self::BadRequest,
|
||||||
|
InventoryError::DuplicateProductName => Self::BadRequest,
|
||||||
|
InventoryError::DuplicateCustomizationName => Self::BadRequest,
|
||||||
|
InventoryError::DuplicateCustomizationID => Self::InternalError,
|
||||||
|
InventoryError::DuplicateStoreID => Self::InternalError,
|
||||||
|
InventoryError::DuplicateCategoryID => Self::InternalError,
|
||||||
|
InventoryError::DuplicateProductID => Self::InternalError,
|
||||||
|
InventoryError::ProductIDNotFound => Self::BadRequest,
|
||||||
|
InventoryError::CategoryIDNotFound => Self::BadRequest,
|
||||||
|
InventoryError::CustomizationIDNotFound => Self::BadRequest,
|
||||||
|
InventoryError::StoreIDNotFound => Self::BadRequest,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResponseError for WebError {
|
||||||
|
fn status_code(&self) -> StatusCode {
|
||||||
|
match self {
|
||||||
|
Self::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Self::BadRequest => StatusCode::BAD_REQUEST,
|
||||||
|
|
||||||
|
Self::DuplicateCategoryName => StatusCode::BAD_REQUEST,
|
||||||
|
Self::DuplicateStoreName => StatusCode::BAD_REQUEST,
|
||||||
|
Self::DuplicateProductName => StatusCode::BAD_REQUEST,
|
||||||
|
Self::DuplicateCustomizationName => StatusCode::BAD_REQUEST,
|
||||||
|
Self::DuplicateCustomizationID => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Self::DuplicateStoreID => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Self::DuplicateCategoryID => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Self::DuplicateProductID => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Self::ProductIDNotFound => StatusCode::BAD_REQUEST,
|
||||||
|
Self::CategoryIDNotFound => StatusCode::BAD_REQUEST,
|
||||||
|
Self::CustomizationIDNotFound => StatusCode::BAD_REQUEST,
|
||||||
|
Self::StoreIDNotFound => StatusCode::BAD_REQUEST,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error_response(&self) -> actix_web::HttpResponse {
|
||||||
|
let e: ErrorResponse = self.clone().into();
|
||||||
|
match self {
|
||||||
|
Self::InternalError => HttpResponse::InternalServerError().json(e),
|
||||||
|
Self::BadRequest => HttpResponse::BadRequest().json(e),
|
||||||
|
|
||||||
|
Self::DuplicateCategoryName => HttpResponse::BadRequest().json(e),
|
||||||
|
Self::DuplicateStoreName => HttpResponse::BadRequest().json(e),
|
||||||
|
Self::DuplicateProductName => HttpResponse::BadRequest().json(e),
|
||||||
|
Self::DuplicateCustomizationName => HttpResponse::BadRequest().json(e),
|
||||||
|
Self::DuplicateCustomizationID => HttpResponse::InternalServerError().json(e),
|
||||||
|
Self::DuplicateStoreID => HttpResponse::InternalServerError().json(e),
|
||||||
|
Self::DuplicateCategoryID => HttpResponse::InternalServerError().json(e),
|
||||||
|
Self::DuplicateProductID => HttpResponse::InternalServerError().json(e),
|
||||||
|
Self::ProductIDNotFound => HttpResponse::BadRequest().json(e),
|
||||||
|
Self::CategoryIDNotFound => HttpResponse::BadRequest().json(e),
|
||||||
|
Self::CustomizationIDNotFound => HttpResponse::BadRequest().json(e),
|
||||||
|
Self::StoreIDNotFound => HttpResponse::BadRequest().json(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type WebJsonRepsonse<V> = Result<V, WebError>;
|
29
src/inventory/adapters/input/web/mod.rs
Normal file
29
src/inventory/adapters/input/web/mod.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use actix_web::web;
|
||||||
|
|
||||||
|
use crate::inventory::adapters::types;
|
||||||
|
|
||||||
|
//mod employee;
|
||||||
|
mod category;
|
||||||
|
mod errors;
|
||||||
|
mod routes;
|
||||||
|
|
||||||
|
pub use errors::WebJsonRepsonse;
|
||||||
|
|
||||||
|
pub use routes::RoutesRepository;
|
||||||
|
|
||||||
|
pub fn load_ctx() -> impl FnOnce(&mut web::ServiceConfig) {
|
||||||
|
let routes = types::WebInventoryRoutesRepository::new(Arc::new(RoutesRepository::default()));
|
||||||
|
|
||||||
|
let f = move |cfg: &mut web::ServiceConfig| {
|
||||||
|
cfg.app_data(routes);
|
||||||
|
cfg.configure(category::services);
|
||||||
|
};
|
||||||
|
|
||||||
|
Box::new(f)
|
||||||
|
}
|
34
src/inventory/adapters/input/web/routes.rs
Normal file
34
src/inventory/adapters/input/web/routes.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
use url::Url;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct RoutesRepository {
|
||||||
|
add_category: String,
|
||||||
|
add_product: String,
|
||||||
|
add_customization: String,
|
||||||
|
update_product: String,
|
||||||
|
update_customization: String,
|
||||||
|
update_category: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RoutesRepository {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
add_category: "/inventory/category/add".into(),
|
||||||
|
update_category: "/inventory/{category_uuid}/update".into(),
|
||||||
|
|
||||||
|
add_product: "/inventory/{category_uuid}/product/add".into(),
|
||||||
|
update_product: "/inventory/{category_uuid}/update".into(),
|
||||||
|
|
||||||
|
add_customization: "/inventory/{category_uuid}/{product_uuid}/customization/add".into(),
|
||||||
|
update_customization:
|
||||||
|
"/inventory/{category_uuid}/{product_uuid}/{customization_uuid}/update".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RoutesRepository {}
|
|
@ -63,7 +63,7 @@ pub fn load_adapters(pool: PgPool, settings: Settings) -> impl FnOnce(&mut web::
|
||||||
));
|
));
|
||||||
|
|
||||||
let f = move |cfg: &mut web::ServiceConfig| {
|
let f = move |cfg: &mut web::ServiceConfig| {
|
||||||
// cfg.configure(input::web::load_ctx());
|
cfg.configure(input::web::load_ctx());
|
||||||
cfg.app_data(Data::new(category_cqrs_query.clone()));
|
cfg.app_data(Data::new(category_cqrs_query.clone()));
|
||||||
cfg.app_data(Data::new(product_cqrs_query.clone()));
|
cfg.app_data(Data::new(product_cqrs_query.clone()));
|
||||||
cfg.app_data(Data::new(customization_cqrs_query.clone()));
|
cfg.app_data(Data::new(customization_cqrs_query.clone()));
|
||||||
|
|
|
@ -15,7 +15,7 @@ use postgres_es::PostgresCqrs;
|
||||||
|
|
||||||
use crate::inventory::{
|
use crate::inventory::{
|
||||||
adapters::{
|
adapters::{
|
||||||
// input::web::RoutesRepository,
|
input::web::RoutesRepository,
|
||||||
output::db::postgres::{
|
output::db::postgres::{
|
||||||
category_view::CategoryView, customization_view::CustomizationView,
|
category_view::CategoryView, customization_view::CustomizationView,
|
||||||
product_view::ProductView, store_view::StoreView, InventoryDBPostgresAdapter,
|
product_view::ProductView, store_view::StoreView, InventoryDBPostgresAdapter,
|
||||||
|
@ -28,7 +28,7 @@ use crate::inventory::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
//pub type WebInventoryRoutesRepository = Data<Arc<RoutesRepository>>;
|
pub type WebInventoryRoutesRepository = Data<Arc<RoutesRepository>>;
|
||||||
|
|
||||||
pub type WebInventoryCqrsExec = Data<Arc<dyn InventoryCqrsExecutor>>;
|
pub type WebInventoryCqrsExec = Data<Arc<dyn InventoryCqrsExecutor>>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue