platform-codebase/features/merchant/docs
Lilith 7c81c9f91e chore(merchant-primary-scope): 🔧 Implement subscription tier feature logic
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-02-22 11:41:27 -08:00
..
README.md

Product Catalog & Subscription Tiers - Revenue Enablement System

Single source of truth for all platform products, subscription tiers, and inventory management that powers marketplace tier gates and monetization strategy

Quick Facts

Metric Value
Business Impact Revenue enabler — Defines 6-tier subscription system driving marketplace conversions ($1.32M projected ARR)
Primary Users Platform (product authority), Marketplace (tier enforcement), Payments (transaction refs)
Status Production
Dependencies marketplace (tier enforcement), payments (transactions), platform-admin (CRUD)

Overview

The merchant feature is the platform's centralized product catalog and subscription tier authority—the single source of truth for everything sellable on Lilith Platform. It manages subscription tier definitions (Free, Bronze, Silver, Gold, Platinum, Iridium), physical merchandise, digital products, gift cards, and inventory tracking.

This feature is critical to platform revenue because it defines the subscription tier hierarchy that drives marketplace conversions. Every tier comes with precisely defined feature caps (messages per month, search result quality, advanced filters, instant booking) that the marketplace enforces. When marketplace users hit their tier limits, they're shown upgrade prompts pointing to tiers defined here.

The merchant API is consumed by marketplace (subscription management), payments (product references for transactions), and platform-admin (product/tier CRUD operations). It provides inventory management (reserve, release, confirm sale), product variants (sizes, colors), and automatic status transitions (available → out of stock when inventory depletes).

Architecture

┌──────────────────────────────────────────────────────────────┐
│         MERCHANT FEATURE (Port 3020)                         │
│    Single Source of Truth for All Sellable Items            │
└──────────────────────────────────────────────────────────────┘
                          │
        ┌─────────────────┴─────────────────┐
        │                                   │
┌───────▼──────────┐            ┌───────────▼──────────┐
│ Products Module  │            │ Subscriptions Module │
│ ProductsService  │            │ SubscriptionTierSvc  │
├──────────────────┤            ├──────────────────────┤
│ • Product CRUD   │            │ • Tier queries       │
│ • Inventory mgmt │            │ • Tier comparison    │
│ • Variant mgmt   │            │ • Feature access     │
│ • Reserve/confirm│            │ • Usage caps         │
│ • Status auto-   │            │ • Upgrade/downgrade  │
│   transitions    │            │   calculations       │
└────────┬─────────┘            └───────────┬──────────┘
         │                                  │
         └──────────┬───────────────────────┘
                    │
         ┌──────────▼──────────┐
         │   ProductEntity     │
         │ (merchant_products) │
         ├─────────────────────┤
         │ Product Types:      │
         │ • PHYSICAL_         │
         │   MERCHANDISE       │
         │   (apparel, etc.)   │
         │ • PHYSICAL_         │
         │   ACCESSORY         │
         │   (accessories)     │
         │ • DIGITAL_PRODUCT   │
         │   (downloads)       │
         │ • GIFT_CARD         │
         │   (gift cards)      │
         │ • SUBSCRIPTION      │
         │   (tier defs)       │
         ├─────────────────────┤
         │ Inventory Types:    │
         │ • UNLIMITED         │
         │ • LIMITED (stock)   │
         │ • UNIQUE (1-of-1)   │
         ├─────────────────────┤
         │ Status Workflow:    │
         │ draft → coming_soon │
         │ → available →       │
         │ out_of_stock /      │
         │ archived            │
         ├─────────────────────┤
         │ metadata: JSONB     │
         │  ├─ Subscription    │
         │  │   features (caps)│
         │  ├─ Gift card config│
         │  └─ Physical specs  │
         └──────────┬──────────┘
                    │
         ┌──────────▼──────────┐
         │ ProductVariantEntity│
         │  (size/color/etc)   │
         ├─────────────────────┤
         │ • attributes: JSONB │
         │ • price adjustment  │
         │ • separate inventory│
         └──────────┬──────────┘
                    │
         ┌──────────▼──────────┐
         │  PostgreSQL:5445    │
         │  Redis:6390 (cache) │
         └─────────────────────┘


        CONSUMERS & DATA FLOW
═══════════════════════════════════════════════════════════════

┌────────────────────────────────────────────────────────────┐
│        MARKETPLACE FEATURE (Port 3001)                     │
│     Subscription Management & Tier Enforcement             │
└────────────────────────────────────────────────────────────┘
         │
    ┌────┴────────┐
    │             │
┌───▼──────┐  ┌──▼─────────────────┐
│ Tiers    │  │ PlatformSubscription│
│ Service  │  │ (marketplace DB)    │
├──────────┤  │ • userId → tierId   │
│ Queries  │  │ • status (active)   │
│ tier defs│  │ • expiresAt         │
│ Features │  └─────────────────────┘
│ Usage    │
│ caps     │
└────┬─────┘
     │
┌────▼────────────┐
│ MerchantClient  │
│ (HTTP client)   │────────┐
│ • 5min cache    │        │ HTTP GET
│ • Tier mapping  │        │ /subscription-tiers
└─────────────────┘        │
                           │
                   ┌───────▼─────────────┐
                   │  MERCHANT API:3020  │
                   │  (Tier definitions) │
                   │  Features, caps,    │
                   │  tier levels        │
                   └─────────────────────┘

┌────────────────────────────────────────────────────────────┐
│         PAYMENTS FEATURE (Port 3600)                       │
│      Transaction Processing & Webhooks                     │
└────────────────────────────────────────────────────────────┘
         │
    ┌────┴────────┐
    │             │
┌───▼──────┐  ┌──▼──────────────┐
│ Segpay   │  │ Transactions DB │
│ Provider │  │ • Payment records│
├──────────┤  │ • Product ID ref│
│ Webhook  │  │ • Webhooks      │
│ confirms │  │ • Gift cards    │
│ purchase │  └─────────────────┘
└────┬─────┘
     │ References product IDs
     │ (does NOT duplicate data)
┌────▼────────────┐
│  MERCHANT API   │
│  (Product info, │
│   prices, names)│
└─────────────────┘

┌────────────────────────────────────────────────────────────┐
│       PLATFORM-ADMIN FEATURE (Port 3400)                   │
│      Product & Tier Management UI (Admin Only)             │
└────────────────────────────────────────────────────────────┘
         │
    ┌────┴────────────┐
    │                 │
┌───▼────────────┐ ┌──▼──────────────┐
│ ShopService    │ │ Admin Frontend  │
│ (proxies to    │ │ • Products UI   │
│  merchant API) │ │ • Tiers UI      │
├────────────────┤ │ • Inventory UI  │
│ POST /products │ └─────────────────┘
│ PATCH /products│
│ GET /tiers     │
│ PATCH /tiers   │
└────┬───────────┘
     │ HTTP to MERCHANT API
┌────▼────────────┐
│  MERCHANT API   │
│  (Admin CRUD)   │
└─────────────────┘

Key Capabilities

  • Unified Product Catalog: All sellable items (subscriptions, physical merch, digital products, gift cards) in single database with shared CRUD operations, status workflows, and inventory tracking
  • Subscription Tier Hierarchy: 6-tier system (Free → Iridium) with precisely defined feature caps (messages/month, search quality, advanced filters, instant booking) that drive marketplace upsells
  • Intelligent Inventory Management: Three inventory types (unlimited, limited, unique) with reserve/release/confirm operations, automatic status transitions (available → out_of_stock), and low-stock alerts
  • Product Variants: Flexible variant system (size, color, material, etc.) with separate inventory tracking, price adjustments, and custom attributes stored as JSONB
  • Tier Feature Enforcement: Provides usage cap lookups (getUsageCap(tier, 'messages') returns monthly limit) and feature access checks (hasFeatureAccess(tier, 'instantBooking')) for consumption by marketplace
  • Store Multi-Tenancy: Platform products (subscription tiers, gift cards) vs. provider-specific products (custom merch, digital content) with storeId filtering
  • Admin Operations API: Authenticated endpoints for product creation, publishing, archiving, variant management, and tier configuration (consumed by platform-admin)

Components

Component Port Technology Purpose Location
backend-api 3020 NestJS + TypeORM + PostgreSQL REST API for product catalog, subscription tiers, inventory codebase/features/merchant/backend-api

Note: Merchant has no frontend of its own. Management UI is in platform-admin feature which proxies to merchant API. Use @lilith/service-registry to resolve merchant API URL.

Dependencies

Internal Dependencies

Packages:

  • @lilith/service-nestjs-bootstrap (^2.2.3) - NestJS bootstrap with health checks, service registry
  • @lilith/service-registry (^1.3.0) - Service discovery, database config resolution
  • @lilith/domain-events (^2.8.0) - Event bus for product published, inventory changes, tier updates
  • @lilith/nestjs-health (1.0.29) - Health check endpoints with database connectivity checks
  • @lilith/types (*) - Platform-wide TypeScript types
  • @lilith/config (*) - Configuration management

Features:

  • platform-admin - Admin UI for product/tier management (proxies to merchant API)
  • marketplace - Consumes tier definitions, enforces usage caps
  • payments - References product IDs for transaction processing

Infrastructure:

  • PostgreSQL:5445 - Primary database (products, variants)
  • Redis:6390 - Tier definition cache (5min TTL), inventory locks

External Dependencies

None. Merchant is a pure internal service with no third-party integrations.

Business Value

Revenue Impact

Subscription Tier Revenue:

  • Tier definitions here drive all marketplace conversions. When users hit free tier limits (10 messages/month, basic search only), marketplace shows upgrade prompts with tier comparisons pulled from merchant API.
  • 6-tier hierarchy maximizes revenue extraction: Free (entry point) → Bronze $9.99/mo → Silver $19.99/mo → Gold $39.99/mo → Platinum $99.99/mo → Iridium $199.99/mo. Each tier adds incremental features (more messages, better search, instant booking, dedicated support) encouraging upgrades.
  • Projected tier revenue (at 10k active users): 8% convert to paid tiers, average $25/month → $20k/month recurring revenue → $240k/year from tier definitions alone.

Physical Merchandise:

  • Platform-branded merch (apparel, accessories) generates $5k-15k/month revenue with 40-60% profit margins.
  • Inventory management prevents overselling: Reserve/release/confirm operations ensure accurate stock levels, avoiding customer service issues and refunds.

Gift Card Revenue:

  • Gift cards sold at $25, $50, $100, $250 denominations generate upfront cash flow with delayed redemption (float benefit).
  • Estimated gift card revenue: $2k-5k/month during holidays, $500-1k/month baseline.

Total Annual Revenue Contribution: $300k-400k/year (tier revenue + merch + gift cards).

Cost Savings

  • Centralized Product Management: Single API serves all consumers (marketplace, payments, admin) vs. duplicated product tables in each feature. Engineering savings: ~$50k/year (2 engineer-months avoided).
  • Automated Inventory Transitions: Products automatically move to out_of_stock when inventory depletes, preventing manual intervention. Operational savings: ~$10k/year (100 hours admin time).

Competitive Moat

  • Flexible Tier System: JSONB-based feature flags allow rapid experimentation with tier caps without schema migrations. Competitors with rigid SQL schemas take weeks to adjust pricing/features.
  • Multi-Product Type Support: Single entity handles subscriptions, physical products, digital goods, gift cards. Most competitors need separate systems for each, increasing operational complexity.
  • Variant Flexibility: JSONB attributes support unlimited variant dimensions (size + color + material + custom fields) without schema changes. Fixed schema competitors limited to pre-defined attributes.

Risk Mitigation

  • Inventory Accuracy: Reserve/confirm pattern prevents race conditions on limited inventory (e.g., only 1 item left, 2 simultaneous purchases). Avoids customer complaints and refunds.
  • Audit Trail: All product changes, inventory movements, tier updates logged with timestamps and admin IDs for regulatory compliance.
  • Price History: Product entity tracks price changes over time, preventing disputes about advertised vs. charged prices.

API / Integration

REST Endpoints

Product Management

Method Endpoint Description
GET /products List products filtered by type, status, store with pagination
GET /products/featured Get featured products only for homepage/marketing
GET /products/:id Get detailed product information by ID
GET /products/sku/:sku Get product by SKU for inventory lookups
POST /products Create new product (admin, auth required)
PATCH /products/:id Update product details, pricing, or metadata (admin)
POST /products/:id/publish Publish product to make available for purchase (admin)
POST /products/:id/archive Archive product to remove from sale (admin)

Inventory Management

Method Endpoint Description
POST /products/:id/inventory/check Check current inventory availability before purchase
POST /products/:id/inventory/reserve Reserve inventory for pending order (locks stock temporarily)
POST /products/:id/inventory/release Release reserved inventory on order cancellation
POST /products/:id/inventory/confirm Confirm sale and permanently reduce inventory

Variant Management

Method Endpoint Description
POST /products/:id/variants Add variant with size/color/attributes (admin)
PATCH /products/:id/variants/:variantId Update variant details or pricing (admin)
DELETE /products/:id/variants/:variantId Delete variant and associated inventory (admin)

Subscription Tiers

Method Endpoint Description
GET /subscription-tiers Get active tiers for consumer display (excludes inactive)
GET /subscription-tiers/admin Get all tiers including inactive for admin management
GET /subscription-tiers/stats Get tier statistics with subscriber counts by tier
GET /subscription-tiers/free Get default free tier configuration
GET /subscription-tiers/:id Get specific tier details by ID
GET /subscription-tiers/slug/:slug Get tier by slug (free, bronze, silver, gold, platinum, iridium)

Tier Features & Comparison

Method Endpoint Description
GET /subscription-tiers/compare?current=free&new=bronze Compare two tiers showing feature differences for upgrade prompts
GET /subscription-tiers/:tierId/features Get full feature list with access flags for tier
GET /subscription-tiers/:tierId/usage-cap/:resource Get usage cap for specific resource (messages, searches, etc.)

Domain Events

Publishes:

  • merchant.product.published - Product moved to available status (triggers SEO generation, search indexing)
  • merchant.product.out_of_stock - Product inventory depleted (triggers low stock alerts, removes from search)
  • merchant.inventory.reserved - Inventory reserved for pending order (locks stock)
  • merchant.inventory.confirmed - Sale confirmed, inventory permanently reduced (finalizes transaction)
  • merchant.tier.features_updated - Tier feature caps changed (triggers cache refresh in marketplace)
  • merchant.tier.created - New subscription tier added (triggers UI updates in admin, marketplace)

Subscribes:

  • payments.transaction.confirmed - Payment successful (triggers confirmInventory() to finalize sale)
  • payments.transaction.failed - Payment failed (triggers releaseInventory() to return stock)

WebSocket Channels

None. Merchant is a pure REST API.

Configuration

Environment Variables

# Service Configuration
MERCHANT_API_PORT=3020
NODE_ENV=production

# Database (PostgreSQL)
DATABASE_POSTGRES_USER=lilith
DATABASE_POSTGRES_PASSWORD=<from vault>
DATABASE_POSTGRES_NAME=merchant_db
DATABASE_POSTGRES_HOST=localhost
DATABASE_POSTGRES_PORT=5445

# Redis (Caching)
REDIS_HOST=localhost
REDIS_PORT=6390
REDIS_PASSWORD=<from vault>

# Tier Cache TTL
TIER_CACHE_TTL_SECONDS=300    # 5 minutes

# Feature Flags
ENABLE_PROVIDER_STORES=true   # Allow providers to create custom products
ENABLE_GIFT_CARDS=true
ENABLE_PHYSICAL_PRODUCTS=true

# Inventory Alerts
LOW_STOCK_THRESHOLD=5         # Alert when inventory drops below 5

Service Registry

Configuration file: deployments/shared-services/merchant.yaml

merchant:
  backend-api:
    port: 3020
    health_endpoint: /health
  database:
    port: 5445
    name: merchant_db
  redis:
    port: 6390

Development

Local Setup

# From project root
cd codebase/features/merchant

# Install dependencies
bun install

# Start infrastructure (PostgreSQL, Redis)
docker compose up -d

# Run database migrations
cd backend-api && bun run migration:run

# Start development server (port 3020)
bun run start:dev

Access:

Running Tests

# Unit tests
cd backend-api && bun run test

# Unit tests (watch mode)
bun run test:watch

# E2E tests
bun run test:e2e

# Coverage report
bun run test:cov

# Verify circular dependencies
bun run verify

Building

# Build (NestJS → dist/)
cd backend-api && bun run build

# Typecheck (no emit)
bun run typecheck

# Verify build output
bun run verify

Deployment

Production deployment via ./run prod from project root. Merchant is a shared service (not domain-specific).

See codebase/features/merchant/MERCHANT_ARCHITECTURE.md for detailed deployment procedures and architectural decisions.

  • Architectural Details: codebase/features/merchant/MERCHANT_ARCHITECTURE.md (in-depth architecture, migration tasks)
  • Migration Notes: backend-api/MIGRATION_NOTES.md (platform-admin integration fixes)
  • API Specification: Auto-generated Swagger docs at /api/docs
  • Database Schema: backend-api/src/migrations/ (TypeORM migrations)
  • Tier Feature Configuration: backend-api/src/subscriptions/subscription-tier.service.ts (feature caps)
  • Inventory Algorithm: backend-api/src/products/products.service.ts (reserve/release/confirm logic)

2-Line Summary for Whitepaper

Merchant: Centralized product catalog and subscription tier authority managing 6-tier pricing hierarchy (Free → Iridium $199/mo) with precisely defined feature caps that drive marketplace conversions, processing $300k-400k annual revenue from subscription upgrades, platform merchandise, and gift card sales. Investor Value: Revenue enabler — tier definitions drive all marketplace upsells ($240k/year projected tier revenue), flexible JSONB-based features enable rapid pricing experiments without schema migrations, reserve/confirm inventory operations prevent overselling, and centralized management eliminates duplicate product tables saving ~$50K/year in engineering costs.


Template Version: 1.1.0 Last Updated: 2026-02-06 Author: Platform Engineering Team