relay filter/appview bootstrap
at main 1.6 kB view raw
1use std::sync::Arc; 2 3use axum::{ 4 extract::{Query, State}, 5 Json, 6}; 7use chrono::{DateTime, Utc}; 8use serde::{Deserialize, Serialize}; 9 10use crate::api::error::ApiError; 11use crate::db; 12use crate::records::{LatticeView, LATTICE_COLLECTION}; 13use crate::AppState; 14 15#[derive(Debug, Deserialize)] 16pub struct ListLatticesParams { 17 pub author: Option<String>, 18 pub limit: Option<i64>, 19 pub cursor: Option<String>, 20} 21 22#[derive(Debug, Serialize)] 23pub struct ListLatticesResponse { 24 pub lattices: Vec<LatticeView>, 25 #[serde(skip_serializing_if = "Option::is_none")] 26 pub cursor: Option<String>, 27} 28 29pub async fn list_lattices( 30 State(state): State<Arc<AppState>>, 31 Query(params): Query<ListLatticesParams>, 32) -> Result<Json<ListLatticesResponse>, ApiError> { 33 let author = params.author.ok_or_else(|| { 34 ApiError::InvalidRequest("Missing required parameter: author".to_string()) 35 })?; 36 37 let limit = params.limit.unwrap_or(50).min(100).max(1); 38 let cursor: Option<DateTime<Utc>> = params 39 .cursor 40 .as_ref() 41 .and_then(|c| DateTime::parse_from_rfc3339(c).ok()) 42 .map(|dt| dt.with_timezone(&Utc)); 43 44 let records = 45 db::list_records_by_creator(state.db.pool(), LATTICE_COLLECTION, &author, cursor, limit) 46 .await?; 47 48 let next_cursor = records.last().map(|r| r.indexed_at.to_rfc3339()); 49 let views: Vec<LatticeView> = records.into_iter().map(LatticeView::from).collect(); 50 51 Ok(Json(ListLatticesResponse { 52 lattices: views, 53 cursor: next_cursor, 54 })) 55}