484979ad53
Rust/Axum REST API (herbapi-api) with PostgreSQL, S3/Garage, OIDC auth. Dioxus 0.7 WASM frontend (herbapi-ui) with sidebar layout and botanical reference style. 9 SQL migrations covering families, species, cultivars, suppliers, companions, images, users, API tokens.
97 lines
2.8 KiB
Rust
97 lines
2.8 KiB
Rust
use axum::extract::{Path, State};
|
|
use axum::Json;
|
|
|
|
use crate::auth::AuthUser;
|
|
use crate::db::{suppliers as db, models::*};
|
|
use crate::error::{AppError, Result};
|
|
use crate::state::AppState;
|
|
|
|
pub async fn list(State(state): State<AppState>) -> Result<Json<Vec<Supplier>>> {
|
|
let suppliers = db::list(&state.pool).await?;
|
|
Ok(Json(suppliers))
|
|
}
|
|
|
|
pub async fn get_by_slug(
|
|
State(state): State<AppState>,
|
|
Path(slug): Path<String>,
|
|
) -> Result<Json<Supplier>> {
|
|
let supplier = db::get_by_slug(&state.pool, &slug).await?;
|
|
Ok(Json(supplier))
|
|
}
|
|
|
|
pub async fn create(
|
|
State(state): State<AppState>,
|
|
auth: AuthUser,
|
|
Json(req): Json<CreateSupplier>,
|
|
) -> Result<Json<Supplier>> {
|
|
if !auth.can_write() {
|
|
return Err(AppError::Forbidden);
|
|
}
|
|
let supplier = db::create(&state.pool, &req).await?;
|
|
Ok(Json(supplier))
|
|
}
|
|
|
|
pub async fn update(
|
|
State(state): State<AppState>,
|
|
auth: AuthUser,
|
|
Path(r): Path<String>,
|
|
Json(req): Json<CreateSupplier>,
|
|
) -> Result<Json<Supplier>> {
|
|
if !auth.can_write() {
|
|
return Err(AppError::Forbidden);
|
|
}
|
|
let id: uuid::Uuid = r.parse().map_err(|_| AppError::NotFound("invalid id".into()))?;
|
|
let supplier = db::update(&state.pool, id, &req).await?;
|
|
Ok(Json(supplier))
|
|
}
|
|
|
|
pub async fn remove(
|
|
State(state): State<AppState>,
|
|
auth: AuthUser,
|
|
Path(r): Path<String>,
|
|
) -> Result<Json<serde_json::Value>> {
|
|
if !auth.is_admin() {
|
|
return Err(AppError::Forbidden);
|
|
}
|
|
let id: uuid::Uuid = r.parse().map_err(|_| AppError::NotFound("invalid id".into()))?;
|
|
db::delete(&state.pool, id).await?;
|
|
Ok(Json(serde_json::json!({ "deleted": true })))
|
|
}
|
|
|
|
// Cultivar-supplier links
|
|
|
|
pub async fn list_for_cultivar(
|
|
State(state): State<AppState>,
|
|
Path(r): Path<String>,
|
|
) -> Result<Json<Vec<CultivarSupplier>>> {
|
|
let id: uuid::Uuid = r.parse().map_err(|_| AppError::NotFound("invalid id".into()))?;
|
|
let links = db::list_for_cultivar(&state.pool, id).await?;
|
|
Ok(Json(links))
|
|
}
|
|
|
|
pub async fn link_cultivar(
|
|
State(state): State<AppState>,
|
|
auth: AuthUser,
|
|
Path(r): Path<String>,
|
|
Json(req): Json<CreateCultivarSupplier>,
|
|
) -> Result<Json<CultivarSupplier>> {
|
|
if !auth.can_write() {
|
|
return Err(AppError::Forbidden);
|
|
}
|
|
let id: uuid::Uuid = r.parse().map_err(|_| AppError::NotFound("invalid id".into()))?;
|
|
let link = db::link_cultivar(&state.pool, id, &req).await?;
|
|
Ok(Json(link))
|
|
}
|
|
|
|
pub async fn unlink_cultivar(
|
|
State(state): State<AppState>,
|
|
auth: AuthUser,
|
|
Path((cid, sid)): Path<(uuid::Uuid, uuid::Uuid)>,
|
|
) -> Result<Json<serde_json::Value>> {
|
|
if !auth.can_write() {
|
|
return Err(AppError::Forbidden);
|
|
}
|
|
db::unlink_cultivar(&state.pool, cid, sid).await?;
|
|
Ok(Json(serde_json::json!({ "deleted": true })))
|
|
}
|