Store AI welcome image in object storage (MinIO/R2) instead of inlining
The welcome image was inlined as a ~2.6MB data URL in the card, bloating every public-profile fetch. Now it's uploaded to S3-compatible object storage and the profile carries just a URL (profile JSON dropped ~2.6MB -> ~575 bytes). - ObjectStore: add put_object(key, bytes, content_type) + public_url(key). R2Store uploads via a presigned PUT; InMemoryStore keeps bytes for tests. - R2Config: add public_base (R2_PUBLIC_BASE); falls back to endpoint/bucket. - card_service::set_welcome: decode the generated image, upload to welcome/<id>.<ext>, store its public URL as welcome.imageUrl. - docker-compose: add MinIO (S3-compatible, drop-in for R2) + a one-shot that creates a public-read cardclaws-assets bucket for local dev. - web: PublicProfile.welcome.imageUrl (renamed from imageDataUrl); WelcomeHero unchanged. astro check clean. Verified live against MinIO: real Gemini image uploaded, served publicly (HTTP 200, image/png, 1024x1024), profile payload now tiny. Same code path runs against Cloudflare R2 in production (endpoint/creds/public_base only). Gate green (118 tests). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
256f2285b9
commit
63fdc4913b
@@ -241,10 +241,10 @@ async fn welcome_generates_and_appears_on_public_profile() {
|
||||
.await;
|
||||
assert_eq!(status, StatusCode::OK, "set welcome failed: {body}");
|
||||
assert_eq!(body["welcome"]["kind"], "image");
|
||||
assert!(body["welcome"]["imageDataUrl"]
|
||||
assert!(body["welcome"]["imageUrl"]
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.starts_with("data:image/png;base64,"));
|
||||
.contains("welcome/"));
|
||||
|
||||
// Publish -> the public profile exposes the welcome.
|
||||
app.request(
|
||||
@@ -259,10 +259,10 @@ async fn welcome_generates_and_appears_on_public_profile() {
|
||||
.await;
|
||||
assert_eq!(status, StatusCode::OK);
|
||||
assert_eq!(profile["welcome"]["message"], "Great to meet you, I'm Omar");
|
||||
assert!(profile["welcome"]["imageDataUrl"]
|
||||
assert!(profile["welcome"]["imageUrl"]
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.starts_with("data:image/png"));
|
||||
.starts_with("http"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user