Feature: Removing an image from an article As an authenticated RenewCMS user managing the CMS I want to delete an already-uploaded image by its id So that a removed image's file and row are actually gone, and a delete on an unknown article or an unknown image answers 404 the same way every other article write does Background: Given internal/infrastructure/useCases.DeleteImageUseCase.DeleteImage(imageId) already exists and calls image.Repository.Delete(imageId), which returns image.ErrImageNotFound for an unknown id and, on the real ImageRepository, also removes the uploaded file from UPLOAD_DIR, per features/delete_article_cascades_images.feature And this slice changes POST /v1/article/{id}/image's success response (api/handlers/image.Handler.PostImage, features/upload_article_image.feature) to also return the created image's numeric id, so the 201 body becomes {"id": ..., "location": ...}; this lets a client address the image later through this slice's DELETE route And this slice mounts DELETE /v1/article/{articleId}/image/{imageId} in api/router.go, in the same jwtauth Verifier + Authenticator group as POST .../image And this slice adds a DeleteImage method to api/handlers/image.Handler, grows NewHandler's signature to also take DeleteImageUseCase, and wires it in api/router.go And DeleteImage parses articleId and imageId from the URL, answering 400 with apperr.IdUint32ErrorMessage if either isn't a valid uint32 And DeleteImage first calls GetArticleUseCase.GetArticle(articleId); errors.Is(err, article.ErrArticleNotFound) answers 404 with apperr.ArticleNotFoundErrorMessage; this only confirms the article id in the URL names a real article, and does not verify that the image id belongs to that article's Images slice (a shallow existence check on both ids, not an ownership check) And DeleteImage then calls DeleteImageUseCase.DeleteImage(imageId); errors.Is(err, image.ErrImageNotFound) answers 404 with the new apperr.ImageNotFoundErrorMessage = "Image not found"; any other error falls back to the existing generic 500 And on success DeleteImage answers 204 with an empty body, the same shape as DELETE /v1/article/{id} Scenario: Removing an image from an article it belongs to succeeds Given a valid jwt cookie for a user with id 1 And the article repository contains an article with id 1 titled "Backyard Renovation Update" whose Images slice holds image id 10 And the image repository contains an image with id 10 When the client sends DELETE /v1/article/1/image/10 with that cookie Then the response status is 204 And the response body is empty And the image repository no longer contains an image with id 10 Scenario: Removing an image from an unknown article answers 404 and never touches the image repository Given a valid jwt cookie for a user with id 1 And the article repository has no article with id 9999 And the image repository contains an image with id 10 When the client sends DELETE /v1/article/9999/image/10 with that cookie Then the response status is 404 And the response body is the text "Article not found" And the image repository's Delete is never called And the image repository still contains the image with id 10 Scenario: Removing an unknown image from an existing article answers 404 Given a valid jwt cookie for a user with id 1 And the article repository contains an article with id 1 titled "Backyard Renovation Update" And the image repository has no image with id 9999 When the client sends DELETE /v1/article/1/image/9999 with that cookie Then the response status is 404 And the response body is the text "Image not found" Scenario: Removing an image id that belongs to a different article still succeeds, because the check is shallow Given a valid jwt cookie for a user with id 1 And the article repository contains an article with id 1 titled "Backyard Renovation Update" whose Images slice is empty And the article repository contains a second article with id 2 whose Images slice holds image id 10 And the image repository contains an image with id 10 When the client sends DELETE /v1/article/1/image/10 with that cookie Then the response status is 204 And the image repository no longer contains an image with id 10 Scenario: Removing an image still requires authentication Given no jwt cookie is sent And the article repository contains an article with id 1 titled "Backyard Renovation Update" whose Images slice holds image id 10 And the image repository contains an image with id 10 When the client sends DELETE /v1/article/1/image/10 without a cookie Then the response status is 401 And the image repository still contains the image with id 10 Scenario Outline: A malformed id in the URL answers 400 before either repository is touched Given a valid jwt cookie for a user with id 1 When the client sends DELETE /v1/article//image/ with that cookie Then the response status is 400 And the response body is the text "The server expects the ID to be in the format of an unsigned 32-bit integer (uint32)." Examples: | article_id | image_id | | abc | 10 | | 1 | abc |