feat: book instance search API endpoint
This commit is contained in:
parent
44be2c83ba
commit
5d4ece3c34
3 changed files with 62 additions and 3 deletions
|
|
@ -184,6 +184,7 @@ async fn run_server(db: Arc<DatabaseConnection>, port: u16) {
|
|||
.routes(routes!(routes::book_instance::bulk_create_book_instance))
|
||||
.routes(routes!(routes::book_instance::get_bal_owner_book_instances))
|
||||
.routes(routes!(routes::book_instance::get_bal_book_instances_by_ean))
|
||||
.routes(routes!(routes::book_instance::search_bal_book_instances))
|
||||
// Owner API
|
||||
.routes(routes!(routes::owner::get_owner_by_id))
|
||||
.routes(routes!(routes::owner::create_owner))
|
||||
|
|
@ -230,6 +231,7 @@ async fn run_server(db: Arc<DatabaseConnection>, port: u16) {
|
|||
.try_it_out_enabled(true)
|
||||
.filter(true)
|
||||
.display_request_duration(true)
|
||||
.persist_authorization(true)
|
||||
);
|
||||
|
||||
let router = router.merge(swagger);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use crate::{entities::{bal, prelude::*}, routes::auth::Claims, AppState};
|
|||
#[derive(IntoParams)]
|
||||
#[into_params(names("id"), parameter_in = Path)]
|
||||
#[allow(dead_code)]
|
||||
struct BalByIdParams(u32);
|
||||
pub struct BalByIdParams(u32);
|
||||
|
||||
#[axum::debug_handler]
|
||||
#[utoipa::path(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::sync::Arc;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use axum::{extract::{Path, State}, Json};
|
||||
use reqwest::{StatusCode};
|
||||
|
|
@ -6,7 +6,7 @@ use sea_orm::{ActiveModelTrait, ActiveValue::{NotSet, Set}, ColumnTrait, EntityT
|
|||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::IntoParams;
|
||||
|
||||
use crate::{entities::{book, book_instance, prelude::*}, routes::auth::Claims, utils::auth::{user_is_bal_owner, user_is_book_instance_owner, user_is_owner_owner}, AppState};
|
||||
use crate::{entities::{book, book_instance, prelude::*}, routes::{auth::Claims, bal}, utils::auth::{user_is_bal_owner, user_is_book_instance_owner, user_is_owner_owner}, AppState};
|
||||
|
||||
|
||||
#[derive(IntoParams)]
|
||||
|
|
@ -329,3 +329,60 @@ pub async fn get_bal_book_instances_by_ean(
|
|||
(StatusCode::INTERNAL_SERVER_ERROR, Json(vec![]))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, utoipa::ToSchema)]
|
||||
pub struct BookInstanceSearchParams {
|
||||
title: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, utoipa::ToSchema)]
|
||||
pub struct BookInstanceSearchResults {
|
||||
book_instances: Vec<book_instance::Model>,
|
||||
books: HashMap<u32, book::Model>,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/bal/{id}/search",
|
||||
params(bal::BalByIdParams),
|
||||
request_body = BookInstanceSearchParams,
|
||||
security(("jwt" = [])),
|
||||
responses(
|
||||
(status = OK, body = BookInstanceSearchResults, description = "Found book instances in the database"),
|
||||
(status = FORBIDDEN, description = "You do not own the specified bal"),
|
||||
),
|
||||
summary = "Search a BAL for books instances",
|
||||
description = "Lists all book instances that match the requested parameters in a bal",
|
||||
tag = "book-instance-api",
|
||||
)]
|
||||
pub async fn search_bal_book_instances(
|
||||
State(state): State<Arc<AppState>>,
|
||||
claims: Claims,
|
||||
Path(bal_id): Path<u32>,
|
||||
Json(instance_payload): Json<BookInstanceSearchParams>,
|
||||
) -> (StatusCode, Json<Option<BookInstanceSearchResults>>) {
|
||||
if !user_is_bal_owner(claims.user_id, bal_id, state.db_conn.as_ref()).await {
|
||||
return (StatusCode::FORBIDDEN, Json(None));
|
||||
}
|
||||
if let Ok(res) = BookInstance::find()
|
||||
.filter(book_instance::Column::BalId.eq(bal_id))
|
||||
.filter(book_instance::Column::Available.eq(true))
|
||||
.join(JoinType::InnerJoin, book_instance::Relation::Book.def())
|
||||
.filter(book::Column::Title.like(format!("%{}%", instance_payload.title)))
|
||||
.all(state.db_conn.as_ref()).await
|
||||
{
|
||||
let mut book_id_map = HashMap::new();
|
||||
for instance in &res {
|
||||
if book_id_map.get(&instance.book_id).is_none() {
|
||||
book_id_map.insert(instance.book_id, Book::find_by_id(instance.book_id).one(state.db_conn.as_ref()).await.unwrap().unwrap());
|
||||
}
|
||||
}
|
||||
(StatusCode::OK, Json(Some(BookInstanceSearchResults {
|
||||
book_instances: res,
|
||||
books: book_id_map
|
||||
})))
|
||||
} else {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, Json(None))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue