use axum::{Json, extract::Path}; use serde_json::{json, Value}; use crate::{atproto::{did_resolver::{fetch_did_doc, identifier_to_did}, pds_resolver::extract_pds}, errors::api_error::ApiError, third_party::bsky::profile::get_bsky_profile}; #[utoipa::path( get, path = "/user/{identifier}/profile", tag = "user", params( ("identifier" = String, Path, description = "Handle or DID") ), responses( ( status = 200, description = "User Profile", body = serde_json::Value, example = json!({ "description": "A hobbyist developer, coding mainly in rust.", "displayName": "Cheetah", "pfp": "https://pds.ch0.dev/xrpc/com.atproto.sync.getBlob?did=did:plc:l7cbmcfr6ccl2tomlwhxjyxe&cid=bafkreibpdomhybdiwisyzvuimubu7bixwgfwnpdnwggrv6kgj3pskhh6he", "pronouns": "he/him" }) ), ( status = 400, description = "Invalid handle or DID", body = serde_json::Value, example = json!({"error": "invalid handle or DID"}) ), ( status = 404, description = "No handle or PDS found for the DID or failed to fetch record", body = serde_json::Value, example = json!({"error": "No handles found associated with DID"}) ), ( status = 500, description = "Internal error: conversion, Redis, or unknown failure", body = serde_json::Value, example = json!({"error": "An unknown error occurred"}) ), ( status = 502, description = "Upstream resolution failed", body = serde_json::Value, example = json!({"error": "could not resolve identity"}) ) ) )] pub async fn fetch_profile_data(Path(identifier): Path) -> Result, ApiError> { let did = identifier_to_did(identifier.clone()).await?; let doc = fetch_did_doc(did.clone()).await?; let pds = extract_pds(doc.clone()).await?; let (display_name, pronouns, description, pfp) = get_bsky_profile(did, pds).await?; Ok(Json(json!({ "displayName": display_name, "pronouns": pronouns, "description": description, "pfp": pfp, }))) }