From 106166b6ec0e93297d95923dcfd03ec723cd96db Mon Sep 17 00:00:00 2001 From: npub128x7j3pwgm4vs8yra3c42fcgcwcvh94g3luwzkqa376du2q6l0esqcrwch <51cde9442e46eac81c83ec71552708c3b0cb96a88ff8e1581d8fb4de281afbf3@buzz.block.builderlab.xyz> Date: Fri, 31 Jul 2026 17:17:07 -0400 Subject: [PATCH] feat(media): include payload keys in upload records Co-authored-by: npub128x7j3pwgm4vs8yra3c42fcgcwcvh94g3luwzkqa376du2q6l0esqcrwch <51cde9442e46eac81c83ec71552708c3b0cb96a88ff8e1581d8fb4de281afbf3@buzz.block.builderlab.xyz> Signed-off-by: npub128x7j3pwgm4vs8yra3c42fcgcwcvh94g3luwzkqa376du2q6l0esqcrwch <51cde9442e46eac81c83ec71552708c3b0cb96a88ff8e1581d8fb4de281afbf3@buzz.block.builderlab.xyz> --- crates/buzz-media/src/upload_record.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/crates/buzz-media/src/upload_record.rs b/crates/buzz-media/src/upload_record.rs index 42f57fbd26..1d13b8c7ad 100644 --- a/crates/buzz-media/src/upload_record.rs +++ b/crates/buzz-media/src/upload_record.rs @@ -60,8 +60,12 @@ pub struct UploadRecord { pub event_id: String, /// Content hash of the uploaded bytes (64 lowercase hex chars). pub sha256: String, - /// Canonical extension — consumers derive the blob key `{sha256}.{ext}`. + /// Canonical extension; retained for backward-compatible consumers. pub ext: String, + /// Exact payload object key. New consumers prefer this over deriving a + /// legacy flat key from `sha256` and `ext`. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub blob_key: Option, /// Sniffed MIME type of the uploaded bytes. pub mime_type: String, /// Size of the uploaded bytes. @@ -154,6 +158,10 @@ pub async fn record_upload_event( event_id: event_id.clone(), sha256: facts.sha256.to_string(), ext: facts.ext.to_string(), + blob_key: Some( + crate::keys::legacy_blob_key(facts.sha256, facts.ext) + .map_err(|e| crate::error::MediaError::StorageError(e.to_string()))?, + ), mime_type: facts.mime.to_string(), size: facts.size, uploaded_at: facts.uploaded_at, @@ -288,6 +296,7 @@ mod tests { event_id: "01J9W3TEST".into(), sha256: "b".repeat(64), ext: "png".into(), + blob_key: Some(format!("{}.png", "b".repeat(64))), mime_type: "image/png".into(), size: 12345, uploaded_at: 1_783_358_352, @@ -303,6 +312,7 @@ mod tests { assert_eq!(json["version"], 1); assert_eq!(json["ext"], "png"); assert_eq!(json["mime_type"], "image/png"); + assert_eq!(json["blob_key"], format!("{}.png", "b".repeat(64))); assert_eq!(json["size"], 12345); assert_eq!(json["ip"], "203.0.113.7"); assert_eq!(json["port"], 51234); @@ -316,6 +326,7 @@ mod tests { event_id: "01J9W3TEST".into(), sha256: "b".repeat(64), ext: "mp4".into(), + blob_key: None, mime_type: "video/mp4".into(), size: 1, uploaded_at: 0, @@ -330,6 +341,7 @@ mod tests { let json = serde_json::to_value(&record).unwrap(); // Omitted, not null — the consumer contract. assert!(json.get("uploader_name").is_none()); + assert!(json.get("blob_key").is_none()); assert!(json.get("ip").is_none()); assert!(json.get("port").is_none()); } @@ -348,6 +360,7 @@ mod tests { let record: UploadRecord = serde_json::from_str(json).unwrap(); assert_eq!(record.version, 1); assert_eq!(record.ip, None); + assert_eq!(record.blob_key, None); } #[test]