this repo has no description
1use crate::api::repo::record::create_record_internal; 2use crate::auth::BearerAuthAdmin; 3use crate::state::AppState; 4use axum::{ 5 Json, 6 extract::State, 7 http::StatusCode, 8 response::{IntoResponse, Response}, 9}; 10use serde::{Deserialize, Serialize}; 11use serde_json::json; 12use tracing::{error, info}; 13 14#[derive(Deserialize)] 15#[serde(rename_all = "camelCase")] 16pub struct CreateProfileInput { 17 pub did: String, 18 pub display_name: Option<String>, 19 pub description: Option<String>, 20} 21 22#[derive(Deserialize)] 23#[serde(rename_all = "camelCase")] 24pub struct CreateRecordAdminInput { 25 pub did: String, 26 pub collection: String, 27 pub rkey: Option<String>, 28 pub record: serde_json::Value, 29} 30 31#[derive(Serialize)] 32#[serde(rename_all = "camelCase")] 33pub struct CreateProfileOutput { 34 pub uri: String, 35 pub cid: String, 36} 37 38pub async fn create_profile( 39 State(state): State<AppState>, 40 _auth: BearerAuthAdmin, 41 Json(input): Json<CreateProfileInput>, 42) -> Response { 43 let did = input.did.trim(); 44 if did.is_empty() { 45 return ( 46 StatusCode::BAD_REQUEST, 47 Json(json!({"error": "InvalidRequest", "message": "did is required"})), 48 ) 49 .into_response(); 50 } 51 52 let mut profile_record = json!({ 53 "$type": "app.bsky.actor.profile" 54 }); 55 56 if let Some(display_name) = &input.display_name { 57 profile_record["displayName"] = json!(display_name); 58 } 59 if let Some(description) = &input.description { 60 profile_record["description"] = json!(description); 61 } 62 63 match create_record_internal( 64 &state, 65 did, 66 "app.bsky.actor.profile", 67 "self", 68 &profile_record, 69 ) 70 .await 71 { 72 Ok((uri, commit_cid)) => { 73 info!(did = %did, uri = %uri, "Created profile for user"); 74 ( 75 StatusCode::OK, 76 Json(CreateProfileOutput { 77 uri, 78 cid: commit_cid.to_string(), 79 }), 80 ) 81 .into_response() 82 } 83 Err(e) => { 84 error!("Failed to create profile for {}: {}", did, e); 85 ( 86 StatusCode::INTERNAL_SERVER_ERROR, 87 Json(json!({"error": "InternalError", "message": e})), 88 ) 89 .into_response() 90 } 91 } 92} 93 94pub async fn create_record_admin( 95 State(state): State<AppState>, 96 _auth: BearerAuthAdmin, 97 Json(input): Json<CreateRecordAdminInput>, 98) -> Response { 99 let did = input.did.trim(); 100 if did.is_empty() { 101 return ( 102 StatusCode::BAD_REQUEST, 103 Json(json!({"error": "InvalidRequest", "message": "did is required"})), 104 ) 105 .into_response(); 106 } 107 108 let rkey = input 109 .rkey 110 .unwrap_or_else(|| chrono::Utc::now().format("%Y%m%d%H%M%S%f").to_string()); 111 112 match create_record_internal(&state, did, &input.collection, &rkey, &input.record).await { 113 Ok((uri, commit_cid)) => { 114 info!(did = %did, uri = %uri, "Admin created record"); 115 ( 116 StatusCode::OK, 117 Json(CreateProfileOutput { 118 uri, 119 cid: commit_cid.to_string(), 120 }), 121 ) 122 .into_response() 123 } 124 Err(e) => { 125 error!("Failed to create record for {}: {}", did, e); 126 ( 127 StatusCode::INTERNAL_SERVER_ERROR, 128 Json(json!({"error": "InternalError", "message": e})), 129 ) 130 .into_response() 131 } 132 } 133}