docs+fix: Final design review of Seller Management - one real bug found and fixed
Some checks failed
Architecture Governance / architecture (push) Has been cancelled

Principal-architect-level review of the entire Seller Management body
of work (7 prior docs + all touched code), verified against fresh
tsc --noEmit and arch:check runs, not recalled from memory.

Real bug found and fixed (in scope per this mission's "unless
absolutely required" carve-out - a one-line correctness fix to
already-committed code, not new feature work):
AdminSellerManagementPageComponent.sellerManagementEnabled read the
bootstrap snapshot once via a plain signal() at construction, not
reactively via bootstrapRevision() the way UiRuntimeFacade/SeoService
both correctly do elsewhere in this codebase. Fixed to computed() keyed
on bootstrapRevision(). Currently invisible (flag is always false,
signal was never even read in the template) but would have gone stale
the moment bootstrap ever reloaded with the flag true. tsc clean after
the fix.

Findings documented in Seller-Management-Final-Design-Review.md (no
Critical/High severity found anywhere):
- Medium: SellerConfig (bootstrap wire shape) and Seller/SellerBranding
  (domain entity) are two unreconciled type hierarchies for the same
  concept - self-flagged already in BACKEND.md SS11.6, restated here as
  an independently-confirmed finding rather than letting it drift.
- Medium: no reusable capability-guard abstraction exists anywhere in
  the codebase, despite ADR-009/ADR-011 both prescribing "check the
  flag in one place" - ADR-009's own described FeatureFlagService was
  never built. Fine with one consumer, a real drift risk the moment a
  second one needs the same check.
- Medium: the flag's true branch has never been exercised, even
  manually - every verification claim in this whole body of work was
  tested at the flag's real value (false).
- Low/nice-to-have: sellerId typed as bare string instead of the UUID
  alias used everywhere else in the new sellers domain; MarketplaceRef
  vs TenantConfig overlap (deliberate, documented, but worth watching);
  documentation-to-code ratio (8 docs, zero backend bytes) carries a
  consolidation-burden risk, especially the Unified/Split-Orders
  question restated independently in 4 different docs.
- Explicitly checked for and did NOT find: circular dependencies,
  scattered tenant/seller conditionals, over-engineering relative to
  the typed-models-only mandate, or any auth/payment code touched.

Verdict: not an unqualified "ready for implementation" - two Medium
findings should be resolved by decision/small build before real
backend work starts, not because they block anything today but
because both compound in cost the longer they're left unresolved.
Everything actually built (typed foundation, disabled-by-default flag,
Phase 1 UI, plus the bug this review fixed) is solid and ready to
stay exactly as-is. No Critical or High-severity issue found anywhere.
This commit is contained in:
sdarbinyan
2026-07-26 22:56:40 +04:00
parent 9e9c11dff2
commit 96c1527d1b
3 changed files with 204 additions and 4 deletions

View File

@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';
import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { TranslatePipe } from '../../../../i18n/translate.pipe';
import { TranslateService } from '../../../../i18n/translate.service';
@@ -48,9 +48,18 @@ export class AdminSellerManagementPageComponent {
private readonly configService = inject(ConfigService);
private readonly i18n = inject(TranslateService);
protected readonly sellerManagementEnabled = signal(
this.configService.getBootstrapSnapshot()?.modules?.sellerManagement?.enabled ?? false
);
/**
* Reactive, not a one-time snapshot - re-reads on every bootstrap reload
* (same pattern as UiRuntimeFacade/SeoService's bootstrapRevision()-keyed
* effects), so this won't go stale if bootstrap ever reloads with the
* flag now true. Not yet consumed in the template - there is no
* enabled-state UI to gate yet (see class doc comment) - but it must be
* correct now rather than silently wrong later.
*/
protected readonly sellerManagementEnabled = computed(() => {
this.configService.bootstrapRevision();
return this.configService.getBootstrapSnapshot()?.modules?.sellerManagement?.enabled ?? false;
});
protected readonly requestDialogOpen = signal(false);
protected readonly successDialogOpen = signal(false);