Skip to content

feat: Fase 4 — Category Management: BROWSER-VERIFIED#128

Merged
edsonwade merged 1 commit into
mainfrom
develop
Jul 13, 2026
Merged

feat: Fase 4 — Category Management: BROWSER-VERIFIED#128
edsonwade merged 1 commit into
mainfrom
develop

Conversation

@edsonwade

Copy link
Copy Markdown
Owner

Now GET /api/v1/categories → 200 OK. Gateway route works. Let me see the page.

The categories list loads with all seeded categories, edit (pencil) + delete (trash) actions per row. Now testing CREATE. Clicking "+ Add category".

The "New category" form dialog opened (Name required, Description, Create disabled until name entered). Filling it.

POST → 201 Created (the 401→201 is the normal token-refresh-and-retry via the interceptor). Then the list refetched. Let me confirm the new category appears.

Dialog closed, list refetched. The new category has a high generated id so it's lower in the list. Let me confirm it's present via the list response.

CREATE confirmed{"id":1402,"name":"Webcams F4",...} is now in the list (id generated from category_seq, no collision — exactly as I verified). Now testing that it appears in the ProductForm dropdown (the key cross-feature check). Opening the seller product form as admin.

The New product form loaded with a Category dropdown. Opening it to confirm "Webcams F4" appears.

The dropdown is populated. "Webcams F4" is at the bottom (after Microphones). Scrolling the dropdown to confirm.

"Webcams F4" appears at the bottom of the ProductForm dropdown — the cross-feature integration works (a category created via the new /categories endpoint shows in the product form's /products/categories dropdown). Closing this and testing UPDATE (rename) and the 409 delete-guard back on the categories page.

Now testing the 409 delete-guard — trying to delete "Keyboards" (which has products). Let me locate its delete button.

"Keyboards" (id 1, has products) delete button is ref_45. Clicking it → confirm → expecting the 409 guard.

Confirm dialog: "'Keyboards' will be removed. If any product still uses it, the delete is rejected." Clicking Delete — expecting a 409 and a clean toast.

DELETE /categories/1 → 409 Conflict — the delete-guard works. Let me confirm the clean toast + that Keyboards is still in the list.

The 409 is clean and message-keyed: category.delete.has.products → "Category [Keyboards] cannot be deleted because [16] product(s) still reference it." Keyboards stays in the list. Now testing UPDATE (rename) on the new "Webcams F4" — locating its edit button via DOM.

"Edit category" dialog opened, prefilled with "Webcams F4" + its description. Renaming it.

PUT /categories/1402 → 200 OK — rename works. Now the final case: DELETE an unreferenced category (Webcams F4 Renamed has no products → should succeed), which also cleans up the test artifact.

DELETE /categories/1402 → 204 No Content — unreferenced delete succeeds, and the test artifact is cleaned up. Let me confirm it's gone from the list.

Full CRUD cycle verified and the test artifact is cleaned up (back to the original 25 categories). One last contract path — the duplicate-name 409. Quick test: create "Monitors" (already exists).

The "POST" filter matched URLs not methods. Let me check the categories requests for the duplicate attempt.

POST "Monitors" → 409 Conflict — duplicate-name guard works. Let me confirm the response body and the toast.

The 409 is clean and message-keyed: category.name.exists → "A category with the name [Monitors] already exists." The form stays open so the admin can fix the name (correct UX). Closing the dialog.

F4 is fully verified in production. Every path exercised end-to-end in the browser:

Fase 4 — Category Management: BROWSER-VERIFIED ✅

Flow Result Evidence
List GET /categories → 200, all 25 seeded categories render with edit/delete actions
Create POST /categories → 201, "Webcams F4" got id 1402 from category_seq (no collision — as I'd verified), tenant_id stamped (no NOT-NULL 500)
Dropdown integration "Webcams F4" appeared in the ProductForm category dropdown — the new /categories endpoint and the storefront's /products/categories share the DB, invalidation works
Delete-guard (409) DELETE /categories/1 → 409 category.name.exists... → "Category [Keyboards] cannot be deleted because [16] product(s) still reference it." Keyboards stayed in the list
Update (rename) PUT /categories/1402 → 200, renamed to "Webcams F4 Renamed"
Delete unreferenced DELETE /categories/1402 → 204, removed cleanly — test artifact cleaned up, list back to original 25
Duplicate name (409) POST "Monitors" → 409 category.name.exists → "A category with the name [Monitors] already exists.", form stays open to fix

The real bug this verification caught: the gateway didn't route /api/v1/categories (only /api/v1/products/**). Fixed the gateway route + public-paths in both sources of truth (config-service yml + docker-compose env), you recreated the gateway, and now every path works. That's exactly why we verify in the browser and not just with green tests — the unit/integration/BDD suites all pass but couldn't see the gateway gap.

Left clean: no test artifacts in the DB (the Webcams category I created was deleted as the final test case). The earlier F3 artifacts (seller id 20, product #6652) are still there from that session.

Fase 4 is done and proven. Next in the plan is F5 — order fulfillment statuses (order-service: SHIPPED/DELIVERED/REFUNDED, migration V1_14, and auditing every OrderStatus switch including the saga timeout scheduler). Want me to start F5?

@edsonwade edsonwade self-assigned this Jul 13, 2026
@edsonwade edsonwade added documentation Improvements or additions to documentation enhancement New feature or request dependencies Pull requests that update a dependency file labels Jul 13, 2026
@edsonwade
edsonwade merged commit fef9574 into main Jul 13, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant