6.8 KiB
6.8 KiB
Implementation Plan: Job 915 — Enable Admin Blog Post Deletion Confirmation
Status
The requested job is not fully implemented. The backend DELETE endpoint, persistence service, Angular API client, parent delete workflow, and confirmation modal already exist, but the parent binds the modal's disabled state to the selected post rather than the request-in-flight state. The UI therefore cannot complete an otherwise wired deletion flow.
1. Architectural Reconnaissance
- Codebase style & conventions: Node.js npm-workspace monorepo using TypeScript, NestJS 10 on the backend, and Angular 17 standalone components on the frontend. Angular admin pages use smart/container components with
signal()state, signal inputs/outputs,ChangeDetectionStrategy.OnPush, and Angular control-flow syntax. The admin blog parent owns service calls and modal lifecycle;BlogDeleteModalComponentis presentational and only receives inputs/emits cancel/confirm events. - Data Layer: TypeORM
BlogPostEntitybacked by SQLite viabetter-sqlite3. Blog deletion is already implemented inbackend/src/modules/blog/admin-blog.service.ts:65-69with a repository lookup, not-found error, anddelete({ id }); no schema or migration change is required. - Test Framework & Structure: Root Jest multi-project configuration in
tests/jest.config.js, with frontend tests under the dedicatedtests/frontend/folder and backend tests undertests/backend/. The rootnpm testcommand runs all projects; focused frontend execution is available throughnpm run test:frontend. Existing blog tests are mostly pure-logic/source-contract tests, while the API suite already covers DELETE persistence and 404 behavior. - Required Tools & Dependencies: No new package or system dependency is required. Existing Node/npm, Angular, Jest, jsdom, ts-jest, and repository dependencies are sufficient.
setup.shneeds no change; it already installs dependencies, rebuildsbetter-sqlite3, and builds both workspaces. No/datafixture or persistent test asset is needed because this is a frontend state-binding fix and existing backend tests use in-memory SQLite.
2. Impacted Files
- To Modify:
frontend/src/app/features/admin/blog/blog.component.ts— bind the delete modal'sdeletinginput toactionInFlight()rather thandeleting() !== null, preserving the selected post while enabling confirmation before the request starts and disabling it during the request.tests/frontend/blog-admin-delete.spec.ts— add a minimal focused regression test in the dedicated frontend test folder covering the modal binding and deletion state contract.
- To Create:
tests/frontend/blog-admin-delete.spec.ts— new focused frontend regression test file, if no existing delete-modal/admin-page test is suitable for extension.
No backend controller, service, entity, DTO, route, database migration, API client, delete modal component, documentation, dependency manifest, or setup script needs modification.
3. Proposed Changes
-
Database / Schema Migration:
- No change.
AdminBlogService.remove()already deletes the requestedblog_postrow and returns not-found for a missing ID. - Do not add migration or seed data. The expected persistence behavior is already provided by the existing DELETE API and is covered by
tests/backend/blog-admin.spec.ts:220-240.
- No change.
-
Backend Logic & APIs:
- No change.
AdminBlogController.remove()already exposesDELETE /api/v1/admin/blog/posts/:id, applies the admin guard/role protection, and returns HTTP 204. BlogApiService.deletePost()already calls the endpoint with the encoded ID and credentials.- The parent
AdminBlogComponent.onDeleteConfirm()already setsactionInFlightto true before awaiting the DELETE request, closes the modal after success, reloads the complete admin list, reportsPost deleted., and resets the in-flight signal infinally. Its error path keeps the modal open and exposes the server message.
- No change.
-
Frontend UI Integration:
- In
frontend/src/app/features/admin/blog/blog.component.ts:111-118, change only the[deleting]binding from[deleting]="deleting() !== null"to[deleting]="actionInFlight()". - Keep
[post]="deleting()"unchanged so the modal continues displaying the selected title and the parent retains the target ID until success or cancel. - Keep the existing
actionInFlightsignal shared by create, edit, and delete operations. WhenopenDelete()sets the selected post and opens the modal,actionInFlight()remains false, sopost-delete-okis enabled. WhenonDeleteConfirm()begins, it becomes true and the modal disables Delete while awaiting the request. On success,closeModal()clears the selection andload()refreshes the table; on failure, the selection/modal remain visible and the button is re-enabled afterfinallyso retry is possible. - Do not change
BlogDeleteModalComponent: its[disabled]="deleting()"behavior is already correct when supplied the proper request-state signal.
- In
4. Test Strategy
- Target Unit Test File: Add
tests/frontend/blog-admin-delete.spec.tsunder the existing dedicated Jest frontend test root. The test should be minimal and focused on the regression contract, not a browser/UI visual test. - Test cases:
- Read/verify the admin component template contract that the delete modal receives
actionInFlight()for itsdeletinginput, and that it no longer derives the disabled state from the selecteddeleting()post. This matches the repository's existing lightweight source-contract testing style and directly catches reintroduction of the bug. - Optionally instantiate the standalone
BlogDeleteModalComponentwith signal inputs using the existing Jest/jsdom Angular setup, setdeletingfalse and true viafixture.componentRef.setInput, rundetectChanges(), and assert the confirm button is enabled before the request and disabled during it. Keep this only if the current test environment supports standalone component compilation without introducing infrastructure; otherwise the source-contract test is sufficient for this one-line wiring regression.
- Read/verify the admin component template contract that the delete modal receives
- Mocking Strategy: Do not involve HTTP, the backend, SQLite, authentication, or real navigation in the focused frontend test. If component instantiation is used, provide only the modal's standalone imports and use signal input APIs; no service mock is needed because the modal emits outputs and contains no service dependency. The existing backend DELETE integration test remains the persistence/error boundary test.
- Verification: Run the single root command
npm testafter implementation so both existing backend API coverage and the new frontend regression test execute. The implementer should also run the repository's available frontend-focused Jest project if needed during iteration; no new command or setup change is required.