use axum::{ Json, extract::{Path, State}, http::{HeaderMap, StatusCode}, response::{IntoResponse, Response}, }; use chrono::NaiveDateTime; use serde::Deserialize; use uuid::Uuid; use crate::{ MnemoState, error::CompositeError, logs::{LogAction, LogEntry}, persons::Name, quotes::Quote, users::{ User, auth::{UserAuthRequired, UserAuthenticate}, }, }; pub async fn get_by_id( State(state): State, Path(id): Path, headers: HeaderMap, ) -> Result { let mut conn = state.pool.acquire().await?; User::authenticate(&mut conn, &headers).await?.required()?; Ok(Json(Quote::get_by_id(&mut conn, id).await?).into_response()) } pub async fn get_by_query( State(state): State, headers: HeaderMap, Json(q): Json, ) -> Result { let mut conn = state.pool.acquire().await?; User::authenticate(&mut conn, &headers).await?.required()?; Ok(Json(Quote::get_by_search_query(&mut conn, &q, 20, 0).await?).into_response()) } #[derive(Deserialize)] pub struct QuoteLineForm { pub content: String, pub name_ids: Vec, } #[derive(Deserialize)] pub struct QuoteCreateForm { pub lines: Vec, pub timestamp: NaiveDateTime, pub context: Option, pub location: Option, pub public: bool, } pub async fn create( State(state): State, headers: HeaderMap, Json(form): Json, ) -> Result { let mut tx = state.pool.begin().await?; let u = User::authenticate(&mut tx, &headers).await?.required()?; let mut lines = Vec::with_capacity(form.lines.len()); for l in form.lines { let mut names = Vec::with_capacity(l.name_ids.len()); for id in l.name_ids { names.push(Name::get_by_id(&mut tx, id).await?); } lines.push((l.content, names)); } let q = Quote::create( &mut tx, lines, form.timestamp, form.context, form.location, u.id, form.public, ) .await?; LogEntry::new(&mut tx, u, LogAction::CreateQuote { id: q.id }).await?; tx.commit().await?; Ok((StatusCode::CREATED, Json(q)).into_response()) }