Files
marketplaces/docs/Catalog-Module-Report.md
2026-07-09 02:43:39 +04:00

12 KiB

Catalog Module Report

Scope

Sprint 5 added a Catalog Module on the frozen platform architecture. No backend APIs, authentication, payment, or bootstrap contracts were changed.

The catalog uses existing domain boundaries:

  • Category data: CategoryFacade -> CategoryService -> Category Repository -> existing GET /category
  • Product data: ProductFacade -> ProductDataService -> Product Provider -> existing product/category item endpoints

Implemented Module

Catalog Container

  • src/app/features/website/catalog/containers/catalog-container.component.ts
  • src/app/features/website/catalog/containers/catalog-container.component.html
  • src/app/features/website/catalog/containers/catalog-container.component.scss

Responsibilities implemented:

  • Reads the route category id.
  • Requests category data through CategoryFacade only.
  • Requests product data through ProductFacade only.
  • Determines whether the current category has child categories.
  • Renders category grid when child categories exist.
  • Renders product grid when no child categories exist.
  • Supports root catalog entry with root categories.
  • Handles loading, empty, and error states.
  • Cancels prior category/product data subscriptions when the route changes.

No HttpClient, backend DTO, auth, payment, bootstrap, or tenant-specific logic is used in the container.

Category Grid

  • src/app/features/website/catalog/components/category-grid/category-grid.component.ts
  • src/app/features/website/catalog/components/category-grid/category-grid.component.html
  • src/app/features/website/catalog/components/category-grid/category-grid.component.scss

Reusable category grid implemented with:

  • Input: Category[]
  • Output: selected Category
  • Responsive grid layout
  • Domain model only
  • No data fetching
  • No backend DTOs

Product Grid

  • src/app/features/website/catalog/components/product-grid/product-grid.component.ts
  • src/app/features/website/catalog/components/product-grid/product-grid.component.html
  • src/app/features/website/catalog/components/product-grid/product-grid.component.scss

Reusable product grid implemented with:

  • Input: Product[]
  • Output: selected Product
  • Output: add-to-cart payload
  • Output: product preview id
  • Responsive grid layout
  • Uses existing reusable product card
  • No HttpClient
  • No backend DTOs

Product Card Compatibility

  • src/app/components/product-card/product-card.component.ts
  • src/app/components/product-card/product-card.component.html

Updated the reusable product card to depend on the Product Domain type and added an explicit selected output.

The product card remains input/output-only and does not use services, storage, HttpClient, or environment configuration. It displays image, title, price, discount, badges, and stock.

Catalog State

  • src/app/features/website/catalog/models/catalog-state.model.ts

Prepared future state architecture for:

  • Category
  • Search
  • Sort
  • Price range
  • Attributes
  • Pagination
  • Filters

Backend filtering was intentionally not implemented in this sprint.

Navigation

Updated routes in src/app/app.routes.ts:

  • /catalog
  • /catalog/:id

Both routes load the same catalog container. Legacy category URLs redirect to the catalog route:

  • /category/:id -> /catalog/:id
  • /category/:id/items -> /catalog/:id

Home category links now point to /catalog/:id.

Unlimited Category Depth

Unlimited nesting is supported by the Category Domain tree utilities from Sprint 4. The catalog container does not assume a fixed depth. For any category id, it asks CategoryFacade.getChildren(categoryId):

  • if children exist, it renders the category grid
  • if no children exist, it loads the product grid

This same decision repeats for every category route depth.

Localization

Added catalog translations in:

  • src/app/i18n/en.ts
  • src/app/i18n/ru.ts
  • src/app/i18n/hy.ts
  • src/app/i18n/translations.ts

Validation

Completed checks:

  • Unlimited category depth is supported through facade child lookup and recursive category domain tree utilities.
  • Product grid is reusable and consumes Product[].
  • Category grid is reusable and consumes Category[].
  • Catalog components use domain models only.
  • Catalog data requests go through facades only.
  • DTOs remain isolated outside the catalog module.
  • Catalog module has no HttpClient usage.
  • Product card has no services, storage, HttpClient, or environment usage.
  • Authentication was not modified.
  • Payment was not modified.
  • Bootstrap contracts were not modified.
  • Backend APIs were not modified.

Build validation passed:

npm run build

Stop Point

Catalog Module implementation is complete for Sprint 5. Stop here for approval before starting the next module or any Builder/Backoffice work.

Sprint 10.2 Catalog UX Polish

Sprint 10.2 improves catalog UX and responsiveness without changing facades, business logic, bootstrap flow, runtime architecture, routing, authentication, or payment.

Empty State Behavior

Two separate states are now rendered in the catalog container:

  • Empty category state (rawProducts.length === 0):
    • hides filter/sort/layout/result controls
    • shows dedicated empty category component with icon, category context, friendly message, and "Browse Categories" action
  • Filtered empty state (rawProducts.length > 0 && products.length === 0):
    • shows "no filter match" message
    • provides "Clear Filters" action
    • keeps filter access available (sidebar on desktop, drawer trigger on tablet/mobile)

Mobile Filter Drawer

  • Desktop keeps visible sticky sidebar filters.
  • Tablet and mobile switch to a drawer-based filter UI.
  • Drawer includes filter groups, Reset, and Apply actions.
  • Apply closes the drawer.
  • Accessibility:
    • drawer uses dialog semantics (role="dialog", aria-modal="true")
    • focus trap is enabled while drawer is open
    • Esc closes the drawer

Mobile Sort

  • Desktop keeps dropdown sort control.
  • Tablet keeps compact dropdown with drawer-based filters.
  • Mobile opens a bottom-sheet sort modal.
  • Supported mobile sort options:
    • Recommended
    • Newest
    • Price Low -> High
    • Price High -> Low
    • Rating
    • Popularity

Responsive Grid Modes and Toolbar

  • Grid selector uses icon buttons and keeps active-state highlighting.
  • Mobile sticky toolbar added with quick actions:
    • Filters
    • Sort
    • Grid cycle
  • Grid cycle rotates through supported layouts while preserving existing layout architecture.

Responsive Spacing and Overflow

Catalog spacing and controls were polished for desktop/tablet/mobile:

  • filter/input/button spacing
  • sort/reset row behavior (single row on desktop, stacked naturally on mobile)
  • card and grid spacing
  • search block spacing
  • drawer/sheet interaction surfaces
  • horizontal overflow prevention

Sprint UI Polish (Visual Only)

This sprint applies visual and responsive UX polish only. No facade contracts, business logic, API contracts, runtime/bootstrap architecture, or widget contracts were changed.

Desktop Layout

  • Catalog products section uses a cleaner two-column structure with consistent spacing tokens (8/12/16/24/32).
  • Filters panel remains sticky on desktop and uses collapsible sections with smooth expand/collapse animation.
  • Product cards keep consistent image height/aspect ratio and improved vertical rhythm between image/title/rating/price/actions.
  • Product action controls are vertical floating circles in the image top-right zone with fixed spacing and no overlap.

Tablet Layout

  • Sidebar filters transition into drawer interaction for better content width.
  • Sort and layout controls retain consistent sizing and spacing.
  • Grid/list results avoid horizontal overflow and preserve button/input containment.

Mobile Layout

  • Permanent sidebar is hidden.
  • Sticky toolbar provides three entry points: Filters, Sort, Grid.
  • Filters open in drawer form with scrollable content and fixed bottom actions.
  • Sort and Grid open bottom-sheet style dialogs.
  • Focus states and keyboard dismissal (Esc) are preserved for all overlays.

Grid Types

  • grid
  • large-grid
  • compact-grid
  • list

All grid switch icons are normalized in size and selected state is visually highlighted.

Filter Drawer and Sections

  • Filter groups (Price, Availability, Rating, Brand, etc.) are collapsible.
  • Range inputs are stacked vertically (From, To) with full-width controls and 12px+ spacing.
  • Slider remains below price inputs for predictable scan order.

Product Card Anatomy

  • Image area: square ratio, object-fit: contain, padded image content.
  • Status elements (discount/stock/badges) positioned to avoid action collisions.
  • Actions: top-right vertical controls with equal circular dimensions.
  • Content: title, optional description, rating, pricing, stock indicator, CTA.

Animations

  • Card hover: subtle elevation + translateY(-2px).
  • Button/selector transitions: ~180-200ms.
  • Filter group expand/collapse: smooth height/opacity transition.
  • Drawer and sheet overlays: subtle slide/fade entrance.

Empty and Loading States

  • Empty results state keeps friendly message and action while hiding non-essential catalog controls when no products are rendered.
  • Skeletons for cards/results keep stable heights to reduce layout shift.

Accessibility Notes

  • Added/standardized visible :focus-visible outlines for interactive elements.
  • Product quick action controls now expose aria labels.
  • Modal/drawer interactions continue to use dialog semantics and focus trap.

Localization and Accessibility

  • New strings for empty states, drawer/sheet UI, and toolbar were added to all languages:
    • src/app/i18n/en.ts
    • src/app/i18n/ru.ts
    • src/app/i18n/hy.ts
    • src/app/i18n/translations.ts
  • No hardcoded catalog UX strings were introduced for Sprint 10.2 additions.

Sprint 11 Search & Discovery Engine

Sprint 11 introduces a reusable, backend-driven Search and Discovery architecture while preserving platform boundaries and existing domain models.

Search Domain Models

Core search models were added under:

  • src/app/core/search/models/search.model.ts
  • src/app/core/search/models/search-state.model.ts

Model coverage includes:

  • SearchQuery
  • SearchResult
  • FilterGroup
  • FilterOption
  • SortOption
  • SearchSuggestion
  • SearchHistory
  • SearchState

Search Entry Point

  • src/app/facades/platform/search.facade.ts

SearchFacade is now the search orchestration entry point for the catalog UX and provides:

  • backend catalog loading bridge for search query payloads
  • metadata-driven sort option generation
  • metadata-driven dynamic filter group generation
  • live suggestions generation
  • in-memory filter metadata memoization
  • reusable filtering, sorting, and pagination helpers
  • query param serialization/deserialization for URL synchronization

History Service

  • src/app/core/search/services/search-history.service.ts

Search history moved to a reusable core service with:

  • recent search tracking
  • popular search support
  • clear/reset support

Catalog UI Integration

Catalog UI now consumes Search domain metadata and state:

  • src/app/features/website/catalog/containers/catalog-container.component.ts
  • src/app/features/website/catalog/components/search-box/search-box.component.ts
  • src/app/features/website/catalog/components/filters-panel/filters-panel.component.ts
  • src/app/features/website/catalog/components/sorting-control/sorting-control.component.ts

Implemented behaviors:

  • live suggestions
  • recent + popular searches
  • keyboard navigation in search box (up/down/enter/escape)
  • clear search action
  • dynamic filters for checkbox, radio, toggle, range, slider, color, size, rating, availability
  • URL query synchronization with SearchState
  • page reload restore from query params

Validation

Completed validation for Sprint 11 integration:

  • npm run build passes successfully
  • facades remain the UI data boundary
  • no authentication changes
  • no payment changes
  • no bootstrap/runtime contract changes