Files
Zumri-Backend/Documentation/PHASE_4_CATALOGUE_CONTENT.md
Sathira Sri Sathara 5643d89236 feat: implement business pricing service and money utilities
- Added `businessPricing.service.js` to handle business customer pricing logic.
- Introduced `money.js` for money parsing, formatting, and calculations.
- Created `pricing.service.js` to manage variant quoting and promotion application.
- Updated validation schemas in `catalogue.schemas.js` and `inventoryMerchandising.schemas.js` for new pricing and inventory features.
- Implemented cron job for inventory reservation expiry in `inventoryReservationExpiry.cron.js`.
- Created database migrations for catalogue and inventory structures.
- Added unit tests for catalogue localization, validation, and inventory merchandising functionalities.
2026-09-03 19:25:13 +05:30

6.9 KiB
Raw Permalink Blame History

ZUMRI Phase 4 Catalogue and Content

Objective

Create the product/content foundation required before inventory and shopping, with no stock, reservation, wholesale-pricing, cart, order, or payment behavior.

Architecture

Catalogue models live under app/models/catalogue, domain services under app/services/catalogue, controllers/routes under their catalogue folders, and one new forward migration owns the schema. Phase 1 RBAC/audit and Phase 2 Upload/storage are reused.

Brand

Brand has immutable identity, unique normalized slug, editorial description, optional owned logo, website, ACTIVE/INACTIVE state, and deterministic order. Names remain language-neutral; no unnecessary BrandTranslation table was added.

Category Hierarchy

Category separates structural code/slug/parent/status from localized content. Root and nested categories are supported. A bounded ancestor walk rejects invalid parents, self-parenting, and cycles. Public APIs offer tree or flat representations.

Product

Product stores structural identity, unique slug/code, brand/default category, DRAFT/ACTIVE/INACTIVE/ARCHIVED state, PUBLIC/HIDDEN visibility, featured flag, publication/new-arrival dates, and audit actors. It stores no stock quantity.

Product Variants

Variants carry globally unique SKU, optional barcode, state, DECIMAL(15,2) base/compare-at prices, ISO-style currency code, optional weight, and order. No inventory columns exist.

Product Options

Normalized ProductOption and ProductOptionValue records define variant dimensions. VariantOptionValue links validated same-product values. ProductAttribute holds non-variant descriptive facts separately.

Pricing Boundary

Phase 4 persists catalogue display price and optional comparison price only. Decimal values remain strings in validation/serialization. Promotions, coupons, business tiers, wholesale/MOQ/volume pricing, and final checkout pricing are excluded.

Product Media

ProductMedia associates Phase 2 Upload records with products and optional same-product variants. Only supported image uploads may be linked. Primary selection is transactional. Upload metadata moves from administrator ownership to CATALOGUE/Product ownership. Public access uses short signed URLs and never exposes storage internals.

Localization

ProductTranslation and CategoryTranslation enforce one row per en|si|ta locale. CollectionTranslation localizes editorial collections. Resolution uses explicit locale, profile/header language, and English fallback without hardcoded UI translations.

SEO / Slugs

Unique lowercase safe slugs exist for brands, categories, products, and collections. Product/category translations carry meta title/description. Published product slugs are restricted from mutation, so a slug-history subsystem is not currently necessary.

Collections

Collections support type, state, publish window, hero upload, translations, and deterministic CollectionProduct ordering. featured on Product is the canonical global featured flag; collection membership is contextual editorial merchandising.

Size Guides

Reusable SizeGuide records use strictly validated structured column/row JSON and may link to a category or product. Raw arbitrary HTML is prohibited.

Product Relationships

Explicit RELATED, SIMILAR, and COMPLETE_THE_LOOK relations are unique and reject self-relations. They are curated content, not AI recommendations.

Reviews

Authenticated customer/business-customer accounts may create one pending review per public active product. Rating is 1–5. Public detail exposes APPROVED reviews only. Permission-gated moderation records actor/time and audit events.

Verified Purchase Future Integration

Clients cannot submit verifiedPurchase; it always starts false. A future order subsystem may derive or update it from authoritative completed order lines. Phase 4 fabricates no purchase evidence.

Public Catalogue

Public product/category/brand/collection routes filter state and visibility at query time, resolve localized content, use eager associations, return small DTOs, compute active-variant price ranges, and hide internal catalogue/storage fields.

Admin Catalogue

Permission-scoped routes support product creation/update/archive, variants, options, media, relations, brands, hierarchical categories, collections, size guides, and review moderation. Product creation is transactional and never deletes pre-existing Upload objects on rollback.

Search and Filtering

MySQL/Sequelize search covers localized name, product code/SKU foundation, and brand name. Filters include category, brand, decimal price bounds, featured, and new arrival. Sort modes are allowlisted. Inventory and wholesale filters are absent. The search boundary can later be replaced without changing public DTOs.

Permissions

Added catalogue.products.read/create/update/delete, catalogue.categories.manage, catalogue.brands.manage, catalogue.collections.manage, catalogue.size-guides.manage, catalogue.reviews.read, and catalogue.reviews.moderate. SUPER_ADMIN retains the Phase 1 bypass.

Audit

Stable events cover product/variant/brand/category/collection creation and updates, publishing/archive, and review submission/moderation. Events store identifiers and concise metadata rather than descriptions or media contents.

Database Changes

20260903040000-phase-4-catalogue-content.js creates only the models used by Phase 4, with foreign keys, uniqueness, state/search indexes, rating/self-relation checks, and DECIMAL prices. It is forward-only and was not run.

Migration pre-checks: identify legacy product/category/brand tables, duplicate slugs/SKUs/barcodes, currency inconsistencies, legacy media ownership, missing/orphan Uploads, and conflicting table names. Back up and resolve explicitly; no data is silently removed. catalogueExample.seeder.js is optional and creates inactive editable examples only.

Tests

Phase 4 tests cover strict schemas, slug/money/rating/locale validation, verified-purchase spoofing, structured size guides, fallback localization, exact decimal comparison, category cycles, and centralized publish requirements. The full Phase 0–3 regression suite remains required.

Remaining Known Issues

The migration and real MySQL constraints/query plans are untested. Staging must validate multi-include pagination, concurrent slug/SKU/media-primary operations, signed-media volume, and actual migration ordering. Review approval/rejection notification was intentionally not enabled to avoid spam without a confirmed product requirement. Product relation projection and full admin update/reorder endpoints can expand when frontend workflows are finalized.

Phase 5 Prerequisites

Complete legacy pre-checks, apply migrations to restored staging, seed permissions, load optional editable content if desired, run public-query EXPLAIN tests with realistic volume, validate signed media and concurrency, and freeze the ProductVariant identifier contract needed by inventory.