From cc615a8e2ab1ac121d83b004380b8947b08d6449 Mon Sep 17 00:00:00 2001 From: Mia Date: Wed, 23 Jul 2025 18:18:14 +0000 Subject: [PATCH] feat(parakeet): really incomplete com.atproto.repo.getRecord impl --- parakeet/src/xrpc/com_atproto/mod.rs | 2 ++ parakeet/src/xrpc/com_atproto/repo.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 file(s) changed, 79 insertion(s)(+), 0 deletion(s)(-) diff --git a/parakeet/src/xrpc/com_atproto/mod.rs b/parakeet/src/xrpc/com_atproto/mod.rs --- a/parakeet/src/xrpc/com_atproto/mod.rs +++ b/parakeet/src/xrpc/com_atproto/mod.rs @@ -2,9 +2,11 @@ use axum::Router; mod identity; +mod repo; #[rustfmt::skip] pub fn routes() -> Router { Router::new() .route("/com.atproto.identity.resolveHandle", get(identity::resolve_handle)) + .route("/com.atproto.repo.getRecord", get(repo::get_record)) } diff --git a/parakeet/src/xrpc/com_atproto/repo.rs b/parakeet/src/xrpc/com_atproto/repo.rs new file mode 100644 --- /dev/null +++ b/parakeet/src/xrpc/com_atproto/repo.rs @@ -0,0 +1,77 @@ +use crate::xrpc::check_actor_status; +use crate::xrpc::error::{Error, XrpcResult}; +use crate::xrpc::extract::AtpAuth; +use crate::GlobalState; +use axum::extract::{Query, State}; +use axum::Json; +use diesel::prelude::*; +use diesel_async::RunQueryDsl; +use parakeet_db::schema; +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +#[derive(Debug, Deserialize)] +pub struct GetRecordQuery { + pub repo: String, + pub collection: String, + pub rkey: String, +} + +#[derive(Debug, Serialize)] +pub struct GetRecordRes { + pub uri: String, + pub cid: String, + pub value: Value, +} + +pub async fn get_record( + State(state): State, + _maybe_auth: Option, + Query(query): Query, +) -> XrpcResult> { + let mut conn = state.pool.get().await?; + + check_actor_status(&mut conn, &query.repo).await?; + + let at_uri = format!("at://{}/{}/{}", &query.repo, &query.collection, &query.rkey); + + let (cid, value) = match query.collection.as_str() { + "app.bsky.feed.generator" => { + // we don't store the full data so this returns partial + let (cid, service_did) = schema::feedgens::table + .select((schema::feedgens::cid, schema::feedgens::service_did)) + .find(&at_uri) + .get_result::<(String, String)>(&mut conn) + .await?; + + ( + cid, + serde_json::json!({ + "$type": "app.bsky.feed.generator", + "did": service_did, + }), + ) + } + "app.bsky.feed.post" => { + schema::posts::table + .select((schema::posts::cid, schema::posts::record)) + .find(&at_uri) + .get_result::<(String, Value)>(&mut conn) + .await? + } + "app.bsky.graph.starterpack" => { + schema::starterpacks::table + .select((schema::starterpacks::cid, schema::starterpacks::record)) + .find(&at_uri) + .get_result::<(String, Value)>(&mut conn) + .await? + } + _ => return Err(Error::invalid_request(None)), + }; + + Ok(Json(GetRecordRes { + uri: at_uri, + cid, + value, + })) +} -- tangled.sh