Epic #705. Two independent breaks stack so per-media deletion silently does nothing:
blog-entry-component.tsremoveMedia() only shows a placeholder snackbar (app.runtime.snackbars.mediaRemovedPlaceholder) — no backend call exists for media removal at all.
The blog-local ConfirmDeleteComponent's Remove button has no (click) handler (confirm-delete.component.html) — it never closes the dialog with true, so even the placeholder path can't fire from the dialog.
Fix shape: backend endpoint (DELETE /posts/{id}/media/{mediaId}, owner-or-staff like post delete) that removes the embedded media entry + purges the artifact via the #422BlogArtifactPurger (single-file, blogs bucket + disk, workflow doc cleanup); Angular wires removeMedia to it. Prefer replacing the broken local dialog with the shared @spikersoft/ui-confirm-dialog (the owner-delete flow in angular #420 shows the pattern — the media preview in the local dialog is the only thing worth keeping).
Priority: high — it's a visible affordance that lies to the user.
Epic #705. Two independent breaks stack so per-media deletion silently does nothing:
1. `blog-entry-component.ts` `removeMedia()` only shows a placeholder snackbar (`app.runtime.snackbars.mediaRemovedPlaceholder`) — no backend call exists for media removal at all.
2. The blog-local `ConfirmDeleteComponent`'s **Remove button has no `(click)` handler** (`confirm-delete.component.html`) — it never closes the dialog with `true`, so even the placeholder path can't fire from the dialog.
**Fix shape:** backend endpoint (DELETE `/posts/{id}/media/{mediaId}`, owner-or-staff like post delete) that removes the embedded media entry + purges the artifact via the #422 `BlogArtifactPurger` (single-file, `blogs` bucket + disk, workflow doc cleanup); Angular wires `removeMedia` to it. Prefer replacing the broken local dialog with the shared `@spikersoft/ui-confirm-dialog` (the owner-delete flow in angular #420 shows the pattern — the media preview in the local dialog is the only thing worth keeping).
Priority: high — it's a visible affordance that lies to the user.
Verified fixed end-to-end on master (landed via #747):
Backend endpoint exists — DELETE /api/blog/posts/{postId}/media/{mediaId} → RemoveMediaFromPostCommand (BlogController line 771), owner-or-staff soft delete (the artifact purge path via the #422 purger).
Angular wired — blog-entry-component.removeMedia() now calls blogService.removeMediaFromPost(postId, mediaId) and reloads the shared list; the placeholder snackbar is gone (success shows mediaRemoved, not mediaRemovedPlaceholder).
Confirm dialog fixed — confirm-delete.component.html's Remove button now has [mat-dialog-close]="true" (in-code comment: "this button previously closed with no result, so confirms were dropped"), so afterClosed() receives true and the removal actually runs.
The affordance no longer lies. Closing.
Verified fixed end-to-end on `master` (landed via #747):
1. **Backend endpoint exists** — `DELETE /api/blog/posts/{postId}/media/{mediaId}` → `RemoveMediaFromPostCommand` (`BlogController` line 771), owner-or-staff soft delete (the artifact purge path via the #422 purger).
2. **Angular wired** — `blog-entry-component.removeMedia()` now calls `blogService.removeMediaFromPost(postId, mediaId)` and reloads the shared list; the placeholder snackbar is gone (success shows `mediaRemoved`, not `mediaRemovedPlaceholder`).
3. **Confirm dialog fixed** — `confirm-delete.component.html`'s Remove button now has `[mat-dialog-close]="true"` (in-code comment: "this button previously closed with no result, so confirms were dropped"), so `afterClosed()` receives `true` and the removal actually runs.
The affordance no longer lies. 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.
Epic #705. Two independent breaks stack so per-media deletion silently does nothing:
blog-entry-component.tsremoveMedia()only shows a placeholder snackbar (app.runtime.snackbars.mediaRemovedPlaceholder) — no backend call exists for media removal at all.ConfirmDeleteComponent's Remove button has no(click)handler (confirm-delete.component.html) — it never closes the dialog withtrue, so even the placeholder path can't fire from the dialog.Fix shape: backend endpoint (DELETE
/posts/{id}/media/{mediaId}, owner-or-staff like post delete) that removes the embedded media entry + purges the artifact via the #422BlogArtifactPurger(single-file,blogsbucket + disk, workflow doc cleanup); Angular wiresremoveMediato it. Prefer replacing the broken local dialog with the shared@spikersoft/ui-confirm-dialog(the owner-delete flow in angular #420 shows the pattern — the media preview in the local dialog is the only thing worth keeping).Priority: high — it's a visible affordance that lies to the user.
Verified fixed end-to-end on
master(landed via #747):DELETE /api/blog/posts/{postId}/media/{mediaId}→RemoveMediaFromPostCommand(BlogControllerline 771), owner-or-staff soft delete (the artifact purge path via the #422 purger).blog-entry-component.removeMedia()now callsblogService.removeMediaFromPost(postId, mediaId)and reloads the shared list; the placeholder snackbar is gone (success showsmediaRemoved, notmediaRemovedPlaceholder).confirm-delete.component.html's Remove button now has[mat-dialog-close]="true"(in-code comment: "this button previously closed with no result, so confirms were dropped"), soafterClosed()receivestrueand the removal actually runs.The affordance no longer lies. Closing.