Skip to content

[TASK] Integration — Erli adapter capability wiring + credentials/config validators for Allegro category access #1383

Description

Part of #1381. Depends on #1382.

Problem / Context

Once AllegroCategoryCatalogClient exists (#1382), ErliOfferManagerAdapter needs to expose CategoryBrowser/CategoryParametersReader — but only for connections that actually configured Allegro app credentials, reflected accurately through the is* guards on the resolved adapter instance. connection.supportedCapabilities (consumed today by the bulk-wizard's #1367 capability gate at apps/web/src/features/listings/components/bulk/bulk-wizard.tsx) turned out to be a static, per-adapterKey manifest value, not per-connection-instance — it cannot serve as this signal (see ADR-031 "Correction"); the FE-visible signal is instead a new config.allegroCategoryAccessEnabled boolean (added post-review, PR #1399). Making the class statically implement these capabilities would break that gate for every Erli connection regardless of configuration — see ADR-031 for why this must be a per-instance, runtime-reflected wiring instead.

Proposed Solution

Full detail: docs/plans/implementation-plan-erli-allegro-category-catalog.md § Sub-task 2 (Phase 2).

  1. ErliOfferManagerAdapter (libs/integrations/erli/src/infrastructure/adapters/erli-offer-manager.adapter.ts): add an optional constructor param allegroCategoryCatalog?: AllegroCategoryCatalogClient. Do NOT add CategoryBrowser/CategoryParametersReader to the class's static implements clause. Declare fetchCategories?/fetchCategoryParameters? as optional instance properties, assigned in the constructor only when allegroCategoryCatalog is provided, so isCategoryBrowser/isCategoryParametersReader (typeof adapter.fetchCategories === 'function') correctly reflect per-connection configuration.
  2. ErliAdapterFactory (libs/integrations/erli/src/application/erli-adapter.factory.ts): in createAdapters, check credentials.allegroClientId/allegroClientSecret; when both present, construct AllegroCategoryCatalogClient (environment from config.allegroEnvironment ?? 'production') and pass to the adapter constructor.
  3. Credentials shape validator (libs/integrations/erli/src/infrastructure/adapters/erli-connection-credentials-shape-validator.adapter.ts): enforce "both or neither" for allegroClientId/allegroClientSecret.
  4. Config shape validator (libs/integrations/erli/src/infrastructure/adapters/erli-connection-config-shape-validator.adapter.ts): allegroEnvironment, when present, must be 'sandbox' or 'production'.
  5. Verify (do not assume) that CategoriesCacheService.getAllegroCategories and GET /listings/connections/:connectionId/categories/:categoryId/parameters need NO code changes — a misconfigured Erli connection should behave exactly like today's "adapter doesn't implement this capability" case (empty array / 501), not a new error path.

Classification

Type: Integration
Layer: Application / Infrastructure
File(s): libs/integrations/erli/src/infrastructure/adapters/erli-offer-manager.adapter.ts, libs/integrations/erli/src/application/erli-adapter.factory.ts, libs/integrations/erli/src/infrastructure/adapters/erli-connection-credentials-shape-validator.adapter.ts, libs/integrations/erli/src/infrastructure/adapters/erli-connection-config-shape-validator.adapter.ts

Dependencies

Assumptions

  • No changes needed to apps/api/src/categories/categories-cache.service.ts or apps/api/src/listings/http/listings.controller.ts — both already resolve capabilities generically via getCapabilityAdapter + is* guards.

Acceptance Criteria

  • ErliOfferManagerAdapter instance exposes working fetchCategories/fetchCategoryParameters only when constructed with a valid AllegroCategoryCatalogClient
  • isCategoryBrowser/isCategoryParametersReader return true only for correctly-configured connections
  • Credentials shape validator rejects exactly-one-of allegroClientId/allegroClientSecret
  • Config shape validator rejects invalid allegroEnvironment values
  • Integration test added: apps/api/test/integration/listings/erli-category-catalog.int-spec.ts — covers configured vs unconfigured Erli connections, including the is* guard results and HTTP endpoint behavior (not connection.supportedCapabilities, which is static per-adapterKey)
  • The existing bulk-wizard [BUG] Frontend — bulk offer wizard hides category-parameter step for Allegro (required "Stan" unsettable) #1367 test suite (apps/web/src/features/listings/components/bulk/bulk-edit-modal.test.tsx) passes unmodified
  • Tests added or updated for non-trivial logic
  • No architecture boundary violations (CORE ↔ Integration)

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions