book-upload preview binds bucket-relative coverImage key as <img src> — broken preview for MinIO-served books #881

Closed
opened 2026-07-28 01:59:46 +00:00 by spikerj · 1 comment
Owner

Problem

book-upload.component.html binds [src]="fetchedBookData()!.coverImage", but IBook.coverImage is documented (libraries/spikersoft-models/src/book.ts:21) as a bucket-relative object key (books/<isbn>/covers/x.avif), not a URL. book-upload.component.ts sets it from book.coverImage || book.image, so the preview only renders when the fallback happens to be an absolute URL (e.g. a Google Books books.google.com/books/content?... link). For MinIO-served books the <img> points at a relative key and 404s.

Fix

Prefer coverUrl (the presigned URL, per the book.ts doc: "bind <img src> to this") with coverImage accepted only when it is an absolute http(s) URL; otherwise show the placeholder.

Related: #618, #719, spikersoft-backend#499.

## Problem `book-upload.component.html` binds `[src]="fetchedBookData()!.coverImage"`, but `IBook.coverImage` is documented (`libraries/spikersoft-models/src/book.ts:21`) as a **bucket-relative object key** (`books/&lt;isbn&gt;/covers/x.avif`), not a URL. `book-upload.component.ts` sets it from `book.coverImage || book.image`, so the preview only renders when the fallback happens to be an absolute URL (e.g. a Google Books `books.google.com/books/content?...` link). For MinIO-served books the `&lt;img&gt;` points at a relative key and 404s. ## Fix Prefer `coverUrl` (the presigned URL, per the `book.ts` doc: "bind &lt;img src&gt; to this") with `coverImage` accepted only when it is an absolute `http(s)` URL; otherwise show the placeholder. Related: #618, #719, spikersoft-backend#499.
Author
Owner

Resolved in spikersoft-angular PR #595 (merged to master, 5ca8e589). Verified against origin/master:

  • book-upload.component.ts:72-75 — prefers data.book.coverUrl, accepts coverImage only when it matches /^https?:\/\//, otherwise null. A bucket-relative key can no longer reach an <img src>.
  • book-upload.component.html:106-117@if (coverPreviewUrl(); as cover) renders the image, @else renders .cover-placeholder, so the MinIO-served case degrades to a placeholder instead of a broken image.

Closing.

Resolved in spikersoft-angular PR #595 (merged to `master`, `5ca8e589`). Verified against `origin/master`: - `book-upload.component.ts:72-75` — prefers `data.book.coverUrl`, accepts `coverImage` only when it matches `/^https?:\/\//`, otherwise `null`. A bucket-relative key can no longer reach an `<img src>`. - `book-upload.component.html:106-117` — `@if (coverPreviewUrl(); as cover)` renders the image, `@else` renders `.cover-placeholder`, so the MinIO-served case degrades to a placeholder instead of a broken image. Closing.
Sign in to join this conversation.