|
…
|
||
|---|---|---|
| .. | ||
| 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 capspayments- 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_stockwhen 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 (triggersconfirmInventory()to finalize sale)payments.transaction.failed- Payment failed (triggersreleaseInventory()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:
- API: http://localhost:3020
- API Docs (Swagger): http://localhost:3020/api/docs
- Health Check: http://localhost:3020/health
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.
Related Documentation
- 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