From 907ac2cfe09aa44ff10f8089c59172a1362061fb Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Fri, 24 Jul 2026 10:46:04 +0400 Subject: [PATCH] fix(backoffice): release-candidate walkthrough fixes - Admin Categories CRUD (create/edit/delete/reorder) silently failed end-to-end in local dev: ADMIN_CATEGORIES_GATEWAY resolved strategy.getBackofficeProviderMode(), which (unlike getBootstrapProviderMode()) has no localhost fallback, so it always picked AdminCategoriesApiGateway (real HTTP, 404s here) over the purpose-built AdminCategoriesLocalGateway mock. saveDraft()'s subscribe() has no error branch, so a create/publish click gave zero feedback: the category never saved, dirty stayed true forever, and the unsaved-changes guard then blocked navigation with no explanation. Live-verified end-to-end: created 3 categories, edited, reordered via the keyboard move-up/move-down buttons - all persist correctly now. Fixed by wiring the token to the category-specific strategy.getCategoryProviderMode() (was already defined, just never called) and giving it the same isLocalhost() mock fallback getBootstrapProviderMode() already uses. Production behavior (non-localhost) is unchanged - still resolves to the real API gateway. - Categories list (tree/table/grid views) mislabeled its Edit button 'Edit product' (adminProducts.edit) instead of 'Edit category' - copy-pasted the wrong existing i18n key; adminCategories.edit already exists with the correct translation in en/ru/hy. Not part of the tracked ~178-key missing-translation gap (docs/KNOWN-ISSUES.md) - this key exists and is simply wrong, not missing. Verified live via browser walkthrough of every Backoffice route (dashboard, products list/create/edit, categories list/create/edit/ reorder, orders list/detail, transactions list/detail+audit dialog, customers list/detail, moderation list+reports queue, users, monitoring, analytics, media library) at desktop and mobile widths. Console/network noise from the mock backoffice API 404ing locally is pre-existing and already documented (docs/ADMIN.md's prior bug-hunt audit pass) - not re-reported. Product create/edit CRUD already worked end-to-end (AdminProductsFacade injects its local gateway unconditionally, no swappable-provider mistake there). npx tsc --noEmit and npm run build both green (only the pre-existing 700kB initial-bundle budget warning, already tracked as out of scope). Co-Authored-By: Claude Sonnet 5 --- .../core/providers/runtime-provider-strategy.service.ts | 9 +++++++++ .../components/admin-categories-list.component.html | 4 ++-- .../services/admin-categories-gateway.token.ts | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/app/core/providers/runtime-provider-strategy.service.ts b/src/app/core/providers/runtime-provider-strategy.service.ts index 4660f5e..8c6d907 100644 --- a/src/app/core/providers/runtime-provider-strategy.service.ts +++ b/src/app/core/providers/runtime-provider-strategy.service.ts @@ -48,6 +48,15 @@ export class RuntimeProviderStrategyService { return 'mock'; } + // Same rationale as getBootstrapProviderMode(): the admin Categories CRUD + // gateway has a real local-mock implementation (AdminCategoriesLocalGateway) + // built specifically so create/edit/delete/reorder can be exercised without + // a backend. Local dev has no reachable backoffice API, so fall back to it + // there while production keeps hitting the real API unconditionally. + if ((environment as any).useMockBootstrapOnLocal === true && this.isLocalhost()) { + return 'mock'; + } + return 'api'; } } diff --git a/src/app/features/admin/categories/components/admin-categories-list.component.html b/src/app/features/admin/categories/components/admin-categories-list.component.html index d30783d..082b62b 100644 --- a/src/app/features/admin/categories/components/admin-categories-list.component.html +++ b/src/app/features/admin/categories/components/admin-categories-list.component.html @@ -125,7 +125,7 @@ @if (row.category.deletedAt) { {{ 'adminCategories.restore' | translate }} } @else { - {{ 'adminProducts.edit' | translate }} + {{ 'adminCategories.edit' | translate }} {{ 'adminProducts.delete' | translate }} } @@ -164,7 +164,7 @@ @if (category.deletedAt) { {{ 'adminCategories.restore' | translate }} } @else { - {{ 'adminProducts.edit' | translate }} + {{ 'adminCategories.edit' | translate }} {{ 'adminProducts.delete' | translate }} } diff --git a/src/app/features/admin/categories/services/admin-categories-gateway.token.ts b/src/app/features/admin/categories/services/admin-categories-gateway.token.ts index 74446f2..ad073ab 100644 --- a/src/app/features/admin/categories/services/admin-categories-gateway.token.ts +++ b/src/app/features/admin/categories/services/admin-categories-gateway.token.ts @@ -8,7 +8,7 @@ export const ADMIN_CATEGORIES_GATEWAY = new InjectionToken { const strategy = inject(RuntimeProviderStrategyService); - const mode = strategy.getBackofficeProviderMode(); + const mode = strategy.getCategoryProviderMode(); return mode === 'mock' ? inject(AdminCategoriesLocalGateway) : inject(AdminCategoriesApiGateway); } });