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.
## 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.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
book-upload.component.htmlbinds[src]="fetchedBookData()!.coverImage", butIBook.coverImageis 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.tssets it frombook.coverImage || book.image, so the preview only renders when the fallback happens to be an absolute URL (e.g. a Google Booksbooks.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 thebook.tsdoc: "bind <img src> to this") withcoverImageaccepted only when it is an absolutehttp(s)URL; otherwise show the placeholder.Related: #618, #719, spikersoft-backend#499.
Resolved in spikersoft-angular PR #595 (merged to
master,5ca8e589). Verified againstorigin/master:book-upload.component.ts:72-75— prefersdata.book.coverUrl, acceptscoverImageonly when it matches/^https?:\/\//, otherwisenull. A bucket-relative key can no longer reach an<img src>.book-upload.component.html:106-117—@if (coverPreviewUrl(); as cover)renders the image,@elserenders.cover-placeholder, so the MinIO-served case degrades to a placeholder instead of a broken image.Closing.