feat: Book instance bulk creation endpoint

This commit is contained in:
Ninjdai 2025-08-01 14:46:04 +02:00
parent 62a1d9e2a7
commit d8c29e1ec8
2 changed files with 82 additions and 0 deletions

View file

@ -76,6 +76,8 @@ async fn main() {
.routes(routes!(routes::book_instance::get_book_instance_by_id)) .routes(routes!(routes::book_instance::get_book_instance_by_id))
.routes(routes!(routes::book_instance::create_book_instance)) .routes(routes!(routes::book_instance::create_book_instance))
.routes(routes!(routes::book_instance::update_book_instance)) .routes(routes!(routes::book_instance::update_book_instance))
.routes(routes!(routes::book_instance::sell_book_instance))
.routes(routes!(routes::book_instance::bulk_create_book_instance))
// Owner API // Owner API
.routes(routes!(routes::owner::get_owner_by_id)) .routes(routes!(routes::owner::get_owner_by_id))
.routes(routes!(routes::owner::create_owner)) .routes(routes!(routes::owner::create_owner))

View file

@ -136,3 +136,83 @@ pub async fn update_book_instance(
(StatusCode::NOT_FOUND, Json(None)) (StatusCode::NOT_FOUND, Json(None))
} }
} }
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
pub struct BookInstanceSaleParams {
price: i32,
}
#[axum::debug_handler]
#[utoipa::path(
post,
path = "/book_instance/{id}/sell",
params(BookInstanceByIdParams),
request_body = BookInstanceSaleParams,
responses(
(status = OK, body = book_instance::Model, description = "Successfully sold book instance"),
(status = NOT_FOUND, description = "No book instance with specified id was found"),
),
summary = "Sell a book instance",
description = "Sell a book instance",
tag = "book-instance-api",
)]
pub async fn sell_book_instance(
State(state): State<Arc<AppState>>,
Path(id): Path<u32>,
Json(instance_payload): Json<BookInstanceSaleParams>,
) -> (StatusCode, Json<Option<book_instance::Model>>) {
if let Ok(Some(book_instance)) = BookInstance::find_by_id(id).one(state.db_conn.as_ref()).await {
let mut book_instance: book_instance::ActiveModel = book_instance.into();
book_instance.sold_price = Set(Some(instance_payload.price));
book_instance.status = Set(book_instance::BookStatus::Sold);
match book_instance.update(state.db_conn.as_ref()).await {
Err(e) => {
log::error!(target: "api", "Error while selling book instance from api: {:#?}", e);
(StatusCode::INTERNAL_SERVER_ERROR, Json(None))
},
Ok(res) => {
let model = res.try_into_model().expect("All fields should be set once the book instance is saved");
(StatusCode::OK, Json(Some(model)))
}
}
} else {
(StatusCode::NOT_FOUND, Json(None))
}
}
#[axum::debug_handler]
#[utoipa::path(
post,
path = "/book_instance/bulk",
request_body = Vec<BookInstanceCreateParams>,
responses(
(status = OK, description = "Successfully created book instances"),
),
summary = "Create new book instances in bulk",
description = "Create new book instances in bulk",
tag = "book-instance-api",
)]
pub async fn bulk_create_book_instance(
State(state): State<Arc<AppState>>,
Json(instance_payload): Json<Vec<BookInstanceCreateParams>>,
) -> StatusCode {
let instances = instance_payload
.into_iter()
.map(|p| book_instance::ActiveModel {
book_id: Set(p.book_id),
owner_id: Set(p.owner_id),
price: Set(p.price),
status: Set(book_instance::BookStatus::Available),
..Default::default()
});
match BookInstance::insert_many(instances).exec(state.db_conn.as_ref()).await {
Err(e) => {
log::error!(target: "api", "Error while bulk inserting new book instances: {:#?}", e);
StatusCode::INTERNAL_SERVER_ERROR
},
Ok(_) => StatusCode::OK
}
}