Joey requested a full-scale UI/UX + feature review of learn.spikersoft.com/blog (management surfaces, element positioning, enhancement opportunities). The review's headline gap — authors couldn't delete their own posts — is implemented outside this epic:
spikersoft-backend #422 — retention purge: 7-day window then full erasure (disk media, blogs/quarantine bucket objects, workflow docs with EXIF/GPS PII; moderation audit anonymized)
Epic status roll-up — audited every child against origin/master. Owner-delete shipped; none of the eight UX children have started. Posting once here rather than eight near-identical comments.
#709 is another instance of the pattern this audit keeps hitting.libraries/domain/blog/src/lib/blog.service.ts:183 defines updateBlogPost(dto: UpdateBlogPostDto): Observable<BlogPost> — and git grep -n "updateBlogPost" origin/master -- '*.ts' returns exactly that one line. Server side and service side both exist; no surface calls it. That's the seventh confirmed case in this audit (alongside #593's ExtractChapters, #663's /quiz/{id}/review, #698's registry, #756's DLQ config, #847's Enabled flag, #785's SCSS class).
#715 has become better-documented rather than fixed, which is worth recording. libraries/features/blog/README.md:33 now names it explicitly as a "Code smell", notes it's "same shape as the domain → platform debt that drove Phase 4h's API_BASE_URL DI refactor", and prescribes the fix — add a MEDIA_BASE_URL token (or reuse API_BASE_URL) to @spikersoft/shared-api-config. So the analysis is done and written down; only the change is outstanding. The domain lib itself is clean (libraries/domain/blog/README.md:16-17 — zero boundary warnings since Phase 4h); it's BlogEntryComponent building media URLs from ${environment.baseUrl}${media.url} that remains.
#714 is the one I'd prioritise. Blog has zero Playwright coverage while this epic proposes changing the create flow (#712), the list (#710), the grid (#711) and adding an edit surface (#709). Landing those against no E2E coverage on a user-facing content surface is how #785 shipped green — its specs asserted on the component model while the template was never wired.
Epic scope check: the body describes owner-delete as delivered (backend #422/#423 + angular #420), and that's consistent with what I see. So this epic is one shipped slice plus eight untouched ones — worth deciding whether it stays a single epic or the UX batch gets re-scoped, since nothing has moved on it since 2026-07-19.
**Epic status roll-up** — audited every child against `origin/master`. **Owner-delete shipped; none of the eight UX children have started.** Posting once here rather than eight near-identical comments.
| Child | State | Evidence |
|---|---|---|
| #708 "My posts" management view | ❌ not started | zero `my-posts`/`myPosts` hits in the blog lib or `routes.ts` |
| #709 Author edit UI | ❌ not started | see below — **service method exists, no caller** |
| #710 Pagination UI | ❌ not started | zero `mat-paginator`/`MatPaginator` in `libraries/features/blog/**` |
| #711 Media grid mobile | ❌ not started | `blog-entry-component.html:189` still `cols="3"` |
| #712 Create-flow nav + guard | ❌ not started | `blog-create.ts:276` and `:326` still `setTimeout(() => this.router.navigate(["/blog"]), 1000)`; no `CanDeactivate` anywhere |
| #713 Polish batch | ❌ not started | no shield `matTooltip` found |
| #714 Blog E2E coverage | ❌ not started | **zero** blog spec files under `e2e/playwright/` |
| #715 Two base-URL sources | ❌ not started | still live — and now self-documented, see below |
**#709 is another instance of the pattern this audit keeps hitting.** `libraries/domain/blog/src/lib/blog.service.ts:183` defines `updateBlogPost(dto: UpdateBlogPostDto): Observable<BlogPost>` — and `git grep -n "updateBlogPost" origin/master -- '*.ts'` returns **exactly that one line**. Server side and service side both exist; no surface calls it. That's the seventh confirmed case in this audit (alongside #593's `ExtractChapters`, #663's `/quiz/{id}/review`, #698's registry, #756's DLQ config, #847's `Enabled` flag, #785's SCSS class).
**#715 has become better-documented rather than fixed**, which is worth recording. `libraries/features/blog/README.md:33` now names it explicitly as a **"Code smell"**, notes it's "same shape as the `domain → platform` debt that drove Phase 4h's `API_BASE_URL` DI refactor", and prescribes the fix — add a `MEDIA_BASE_URL` token (or reuse `API_BASE_URL`) to `@spikersoft/shared-api-config`. So the analysis is done and written down; only the change is outstanding. The domain lib itself is clean (`libraries/domain/blog/README.md:16-17` — zero boundary warnings since Phase 4h); it's `BlogEntryComponent` building media URLs from `${environment.baseUrl}${media.url}` that remains.
**#714 is the one I'd prioritise.** Blog has **zero** Playwright coverage while this epic proposes changing the create flow (#712), the list (#710), the grid (#711) and adding an edit surface (#709). Landing those against no E2E coverage on a user-facing content surface is how #785 shipped green — its specs asserted on the component model while the template was never wired.
**Epic scope check:** the body describes owner-delete as delivered (backend #422/#423 + angular #420), and that's consistent with what I see. So this epic is one shipped slice plus eight untouched ones — worth deciding whether it stays a single epic or the UX batch gets re-scoped, since nothing has moved on it since 2026-07-19.
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.
Context
Joey requested a full-scale UI/UX + feature review of learn.spikersoft.com/blog (management surfaces, element positioning, enhancement opportunities). The review's headline gap — authors couldn't delete their own posts — is implemented outside this epic:
blogs/quarantinebucket objects, workflow docs with EXIF/GPS PII; moderation audit anonymized)[Authorize]+ AuthorId from Keycloaksub)Everything else found in the review becomes this epic's children, in rough priority order:
Children
(Each filed as its own ticket referencing this epic; numbers linked in comments below as they're filed.)
Review evidence base
Angular:
libraries/features/blog/**(list/entry/create components),libraries/domain/blog/**(service — full API surface incl. unusedgetMyPosts), routes (/blogpublic,/blog/createauth,/admin/blog-moderationadmin). Backend:BlogController(20 endpoints), 3 Mongo collections, 5-consumer media pipeline. Full traces in the child tickets.Children filed (priority order):
getMyPostsunused)Implementation PRs for the headline feature (outside this epic's scope): backend #422 (retention purge), backend #423 (create provenance), angular #420 (owner-delete UI).
Epic status roll-up — audited every child against
origin/master. Owner-delete shipped; none of the eight UX children have started. Posting once here rather than eight near-identical comments.my-posts/myPostshits in the blog lib orroutes.tsmat-paginator/MatPaginatorinlibraries/features/blog/**blog-entry-component.html:189stillcols="3"blog-create.ts:276and:326stillsetTimeout(() => this.router.navigate(["/blog"]), 1000); noCanDeactivateanywherematTooltipfounde2e/playwright/#709 is another instance of the pattern this audit keeps hitting.
libraries/domain/blog/src/lib/blog.service.ts:183definesupdateBlogPost(dto: UpdateBlogPostDto): Observable<BlogPost>— andgit grep -n "updateBlogPost" origin/master -- '*.ts'returns exactly that one line. Server side and service side both exist; no surface calls it. That's the seventh confirmed case in this audit (alongside #593'sExtractChapters, #663's/quiz/{id}/review, #698's registry, #756's DLQ config, #847'sEnabledflag, #785's SCSS class).#715 has become better-documented rather than fixed, which is worth recording.
libraries/features/blog/README.md:33now names it explicitly as a "Code smell", notes it's "same shape as thedomain → platformdebt that drove Phase 4h'sAPI_BASE_URLDI refactor", and prescribes the fix — add aMEDIA_BASE_URLtoken (or reuseAPI_BASE_URL) to@spikersoft/shared-api-config. So the analysis is done and written down; only the change is outstanding. The domain lib itself is clean (libraries/domain/blog/README.md:16-17— zero boundary warnings since Phase 4h); it'sBlogEntryComponentbuilding media URLs from${environment.baseUrl}${media.url}that remains.#714 is the one I'd prioritise. Blog has zero Playwright coverage while this epic proposes changing the create flow (#712), the list (#710), the grid (#711) and adding an edit surface (#709). Landing those against no E2E coverage on a user-facing content surface is how #785 shipped green — its specs asserted on the component model while the template was never wired.
Epic scope check: the body describes owner-delete as delivered (backend #422/#423 + angular #420), and that's consistent with what I see. So this epic is one shipped slice plus eight untouched ones — worth deciding whether it stays a single epic or the UX batch gets re-scoped, since nothing has moved on it since 2026-07-19.