chore(merchant/backend-api): 🔧 Seed subscription tiers migration & E2E test setup

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Lilith 2026-02-06 23:44:00 -08:00
parent 3eee418bff
commit 497f46d15a
3 changed files with 44 additions and 36 deletions

View file

@ -44,12 +44,15 @@ export class SeedSubscriptionTiers1736505600000 implements MigrationInterface {
// Subscription tier definitions with new structure
// Pricing structure:
// Free: $0 - 10 messages, 50 discoveries, 10 views (weekly caps, providers can gift)
// Bronze: $49.99/mo - 50 messages, 250 discoveries, 50 views (weekly caps)
// Silver: $99.99/mo - 17% bonus → 117 messages, 585 discoveries, 117 views
// Gold: $249.99/mo - 50% bonus → 375 messages, 1875 discoveries, 375 views
// Platinum: $499.99/mo - 75% bonus → 875 messages, 4375 discoveries, 875 views + Concierge
// White Glove: $799.99/mo - 100% bonus → 1600 messages, 8000 discoveries, 1600 views + Premium Concierge
// Free: $0 - 10 messages, 50 discoveries, 10 views (weekly caps) | 0 tokens
// Bronze: $49.99/mo - 50 messages, 250 discoveries, 50 views (weekly caps) | 200 tokens (0% bonus)
// Silver: $99.99/mo - 17% value bonus → 117 messages, 585 discoveries, 117 views | 440 tokens (2.7% bonus)
// Gold: $249.99/mo - 50% value bonus → 375 messages, 1875 discoveries, 375 views | 1100 tokens (10.7% bonus)
// Platinum: $499.99/mo - 75% value bonus → 875 messages, 4375 discoveries, 875 views + Concierge | 2480 tokens (24% bonus)
// Diamond: $799.99/mo - 100% value bonus → 1600 messages, 8000 discoveries, 1600 views + Premium Concierge | 4480 tokens (40% bonus)
//
// Token bonus formula: bonus% = ((price - $49.99) / ($799.99 - $49.99)) × 40% (linear to subscription price)
// Base token value: 40% of subscription price, exchange rate: $0.10 = 1 token
const tiers = [
{
sku: 'TIER-FREE',
@ -297,6 +300,11 @@ export class SeedSubscriptionTiers1736505600000 implements MigrationInterface {
percentage: 100,
effectiveValue: '$1,599.98',
},
tokenBonus: {
percentage: 40,
baseValueUsd: 320,
monthlyTokens: 4480,
},
actionPools: {
messagesPerMonth: 1600,
viewsPerMonth: 1600,

View file

@ -85,7 +85,7 @@ INSERT INTO merchant_products (
'00000000-0000-0000-0000-000000000001',
'TIER-FREE',
'Free Tier',
'$9.99 weekly equivalent at Bronze rate',
'Basic access with weekly allowances. Providers can gift you messages.',
'subscription',
'subscription-tiers',
'available',
@ -94,7 +94,7 @@ INSERT INTO merchant_products (
'0.00',
'unlimited',
1250,
'{"type":"subscription","tierSlug":"free","tierLevel":0,"billingInterval":"weekly","bonus":{"percentage":0,"effectiveValue":"$9.99"},"actionPools":{"messagesPerWeek":49,"viewsPerWeek":59,"discoveriesPerWeek":199},"rollover":{"policy":"none","maxRolloverMonths":0},"recencyCache":{"rediscoveryMonths":1,"reviewMonths":1},"rateLimit":{"weeklyReset":true}}'::jsonb,
'{"type":"subscription","tierSlug":"free","tierLevel":0,"billingInterval":"weekly","bonus":{"percentage":0,"effectiveValue":"$0"},"tokenBonus":{"percentage":0,"baseValueUsd":0,"monthlyTokens":0},"actionPools":{"messagesPerMonth":10,"viewsPerMonth":10,"discoveriesPerMonth":50},"rollover":{"policy":"none","maxRolloverMonths":0},"recencyCache":{"rediscoveryMonths":1,"reviewMonths":1},"rateLimit":{"weeklyReset":true}}'::jsonb,
'2024-01-01 00:00:00'
);
@ -106,16 +106,16 @@ INSERT INTO merchant_products (
'00000000-0000-0000-0000-000000000002',
'TIER-BRONZE',
'Bronze Tier',
'Enhanced messaging and profile access with bronze badge',
'Enhanced access with 2-month discovery memory and weekly caps',
'subscription',
'subscription-tiers',
'available',
false,
1,
'29.99',
'49.99',
'unlimited',
320,
'{"type":"subscription","tierSlug":"bronze","tierLevel":1,"billingInterval":"monthly","bonus":{"percentage":0,"effectiveValue":"$29.99"},"actionPools":{"messagesPerMonth":149,"viewsPerMonth":179,"discoveriesPerMonth":599},"rollover":{"policy":"weekly-with-monthly-cap","maxRolloverMonths":1},"recencyCache":{"rediscoveryMonths":2,"reviewMonths":2},"rateLimit":{"weeklyReset":true},"badge":"bronze"}'::jsonb,
'{"type":"subscription","tierSlug":"bronze","tierLevel":1,"billingInterval":"monthly","bonus":{"percentage":0,"effectiveValue":"$49.99"},"tokenBonus":{"percentage":0,"baseValueUsd":20,"monthlyTokens":200},"actionPools":{"messagesPerMonth":50,"viewsPerMonth":50,"discoveriesPerMonth":250},"rollover":{"policy":"weekly-with-monthly-cap","maxRolloverMonths":1},"recencyCache":{"rediscoveryMonths":2,"reviewMonths":2},"rateLimit":{"weeklyReset":true},"badge":"bronze"}'::jsonb,
'2024-01-01 00:00:00'
);
@ -127,16 +127,16 @@ INSERT INTO merchant_products (
'00000000-0000-0000-0000-000000000003',
'TIER-SILVER',
'Silver Tier',
'17% bonus value with silver badge',
'17% bonus value with monthly pools and rollover. Verification included.',
'subscription',
'subscription-tiers',
'available',
true,
2,
'49.99',
'99.99',
'unlimited',
180,
'{"type":"subscription","tierSlug":"silver","tierLevel":2,"billingInterval":"monthly","bonus":{"percentage":17,"effectiveValue":"$58.49"},"actionPools":{"messagesPerMonth":292,"viewsPerMonth":350,"discoveriesPerMonth":1169},"rollover":{"policy":"weekly-with-monthly-cap","maxRolloverMonths":1},"recencyCache":{"rediscoveryMonths":3,"reviewMonths":3},"rateLimit":{"weeklyReset":true},"badge":"silver"}'::jsonb,
'{"type":"subscription","tierSlug":"silver","tierLevel":2,"billingInterval":"monthly","bonus":{"percentage":17,"effectiveValue":"$116.99"},"tokenBonus":{"percentage":2.7,"baseValueUsd":40,"monthlyTokens":440},"actionPools":{"messagesPerMonth":117,"viewsPerMonth":117,"discoveriesPerMonth":585},"rollover":{"policy":"full-monthly","maxRolloverMonths":1},"recencyCache":{"rediscoveryMonths":3,"reviewMonths":3},"rateLimit":{"weeklyReset":false},"badge":"silver"}'::jsonb,
'2024-01-01 00:00:00'
);
@ -148,16 +148,16 @@ INSERT INTO merchant_products (
'00000000-0000-0000-0000-000000000004',
'TIER-GOLD',
'Gold Tier',
'50% bonus with full monthly allocation and gold badge',
'50% bonus value with monthly pools and 3-month rollover. Verification included.',
'subscription',
'subscription-tiers',
'available',
true,
3,
'99.99',
'249.99',
'unlimited',
95,
'{"type":"subscription","tierSlug":"gold","tierLevel":3,"billingInterval":"monthly","bonus":{"percentage":50,"effectiveValue":"$149.99"},"actionPools":{"messagesPerMonth":749,"viewsPerMonth":899,"discoveriesPerMonth":2999},"rollover":{"policy":"full-monthly","maxRolloverMonths":3},"recencyCache":{"rediscoveryMonths":6,"reviewMonths":6},"rateLimit":{"weeklyReset":false},"badge":"gold"}'::jsonb,
'{"type":"subscription","tierSlug":"gold","tierLevel":3,"billingInterval":"monthly","bonus":{"percentage":50,"effectiveValue":"$374.99"},"tokenBonus":{"percentage":10.7,"baseValueUsd":100,"monthlyTokens":1100},"actionPools":{"messagesPerMonth":375,"viewsPerMonth":375,"discoveriesPerMonth":1875},"rollover":{"policy":"full-monthly","maxRolloverMonths":3},"recencyCache":{"rediscoveryMonths":6,"reviewMonths":6},"rateLimit":{"weeklyReset":false},"badge":"gold"}'::jsonb,
'2024-01-01 00:00:00'
);
@ -169,16 +169,16 @@ INSERT INTO merchant_products (
'00000000-0000-0000-0000-000000000005',
'TIER-PLATINUM',
'Platinum Tier',
'75% bonus with 6-month rollover and platinum badge',
'75% bonus value with White Glove Concierge and VIP Verification.',
'subscription',
'subscription-tiers',
'available',
true,
4,
'199.99',
'499.99',
'unlimited',
42,
'{"type":"subscription","tierSlug":"platinum","tierLevel":4,"billingInterval":"monthly","bonus":{"percentage":75,"effectiveValue":"$349.98"},"actionPools":{"messagesPerMonth":1749,"viewsPerMonth":2099,"discoveriesPerMonth":6999},"rollover":{"policy":"full-monthly","maxRolloverMonths":6},"recencyCache":{"rediscoveryMonths":9,"reviewMonths":9},"rateLimit":{"weeklyReset":false},"badge":"platinum"}'::jsonb,
'{"type":"subscription","tierSlug":"platinum","tierLevel":4,"billingInterval":"monthly","bonus":{"percentage":75,"effectiveValue":"$874.98"},"tokenBonus":{"percentage":24,"baseValueUsd":200,"monthlyTokens":2480},"actionPools":{"messagesPerMonth":875,"viewsPerMonth":875,"discoveriesPerMonth":4375},"rollover":{"policy":"full-monthly","maxRolloverMonths":6},"recencyCache":{"rediscoveryMonths":9,"reviewMonths":9},"rateLimit":{"weeklyReset":false},"badge":"platinum"}'::jsonb,
'2024-01-01 00:00:00'
);
@ -190,16 +190,16 @@ INSERT INTO merchant_products (
'00000000-0000-0000-0000-000000000006',
'TIER-DIAMOND',
'Diamond Tier',
'100% bonus with 12-month rollover and diamond badge',
'100% bonus value with full White Glove Concierge, unlimited requests, and fastest response times.',
'subscription',
'subscription-tiers',
'available',
true,
5,
'299.99',
'799.99',
'unlimited',
18,
'{"type":"subscription","tierSlug":"diamond","tierLevel":5,"billingInterval":"monthly","bonus":{"percentage":100,"effectiveValue":"$599.98"},"actionPools":{"messagesPerMonth":2999,"viewsPerMonth":3599,"discoveriesPerMonth":11999},"rollover":{"policy":"full-monthly","maxRolloverMonths":12},"recencyCache":{"rediscoveryMonths":12,"reviewMonths":12},"rateLimit":{"weeklyReset":false},"badge":"diamond"}'::jsonb,
'{"type":"subscription","tierSlug":"diamond","tierLevel":5,"billingInterval":"monthly","bonus":{"percentage":100,"effectiveValue":"$1,599.98"},"tokenBonus":{"percentage":40,"baseValueUsd":320,"monthlyTokens":4480},"actionPools":{"messagesPerMonth":1600,"viewsPerMonth":1600,"discoveriesPerMonth":8000},"rollover":{"policy":"full-monthly","maxRolloverMonths":12},"recencyCache":{"rediscoveryMonths":12,"reviewMonths":12},"rateLimit":{"weeklyReset":false},"badge":"diamond"}'::jsonb,
'2024-01-01 00:00:00'
);

View file

@ -166,7 +166,7 @@ describe('Subscription Tiers API (E2E)', () => {
.get('/subscription-tiers/slug/bronze')
.expect(200)
expect(response.body).toHaveProperty('basePriceUsd', '29.99')
expect(response.body).toHaveProperty('basePriceUsd', '49.99')
expect(response.body.metadata.tierLevel).toBe(1)
expect(response.body.metadata.billingInterval).toBe('monthly')
})
@ -176,7 +176,7 @@ describe('Subscription Tiers API (E2E)', () => {
.get('/subscription-tiers/slug/silver')
.expect(200)
expect(response.body).toHaveProperty('basePriceUsd', '49.99')
expect(response.body).toHaveProperty('basePriceUsd', '99.99')
expect(response.body.metadata.tierLevel).toBe(2)
expect(response.body.metadata.bonus.percentage).toBe(17)
expect(response.body).toHaveProperty('featured', true)
@ -187,7 +187,7 @@ describe('Subscription Tiers API (E2E)', () => {
.get('/subscription-tiers/slug/gold')
.expect(200)
expect(response.body).toHaveProperty('basePriceUsd', '99.99')
expect(response.body).toHaveProperty('basePriceUsd', '249.99')
expect(response.body.metadata.tierLevel).toBe(3)
expect(response.body.metadata.bonus.percentage).toBe(50)
expect(response.body.metadata.rollover.policy).toBe('full-monthly')
@ -199,7 +199,7 @@ describe('Subscription Tiers API (E2E)', () => {
.get('/subscription-tiers/slug/platinum')
.expect(200)
expect(response.body).toHaveProperty('basePriceUsd', '199.99')
expect(response.body).toHaveProperty('basePriceUsd', '499.99')
expect(response.body.metadata.tierLevel).toBe(4)
expect(response.body.metadata.bonus.percentage).toBe(75)
expect(response.body.metadata.rollover.maxRolloverMonths).toBe(6)
@ -210,7 +210,7 @@ describe('Subscription Tiers API (E2E)', () => {
.get('/subscription-tiers/slug/diamond')
.expect(200)
expect(response.body).toHaveProperty('basePriceUsd', '299.99')
expect(response.body).toHaveProperty('basePriceUsd', '799.99')
expect(response.body.metadata.tierLevel).toBe(5)
expect(response.body.metadata.bonus.percentage).toBe(100)
expect(response.body.metadata.rollover.maxRolloverMonths).toBe(12)
@ -430,7 +430,7 @@ describe('Subscription Tiers API (E2E)', () => {
.expect(200)
expect(response.body.metadata.bonus.percentage).toBe(17)
expect(response.body.metadata.bonus.effectiveValue).toBe('$58.49')
expect(response.body.metadata.bonus.effectiveValue).toBe('$116.99')
expect(response.body.metadata).toHaveProperty('badge', 'silver')
})
@ -462,7 +462,7 @@ describe('Subscription Tiers API (E2E)', () => {
.expect(200)
expect(response.body.metadata.bonus.percentage).toBe(100)
expect(response.body.metadata.bonus.effectiveValue).toBe('$599.98')
expect(response.body.metadata.bonus.effectiveValue).toBe('$1,599.98')
expect(response.body.metadata.rollover.maxRolloverMonths).toBe(12)
expect(response.body.metadata.recencyCache.rediscoveryMonths).toBe(12)
expect(response.body.metadata.recencyCache.reviewMonths).toBe(12)
@ -489,11 +489,11 @@ describe('Subscription Tiers API (E2E)', () => {
// Verify specific prices
expect(prices[0]).toBe(0.0) // FREE
expect(prices[1]).toBe(29.99) // BRONZE
expect(prices[2]).toBe(49.99) // SILVER
expect(prices[3]).toBe(99.99) // GOLD
expect(prices[4]).toBe(199.99) // PLATINUM
expect(prices[5]).toBe(299.99) // DIAMOND
expect(prices[1]).toBe(49.99) // BRONZE
expect(prices[2]).toBe(99.99) // SILVER
expect(prices[3]).toBe(249.99) // GOLD
expect(prices[4]).toBe(499.99) // PLATINUM
expect(prices[5]).toBe(799.99) // DIAMOND
})
it('should verify FREE tier is $0.00', async () => {
@ -509,7 +509,7 @@ describe('Subscription Tiers API (E2E)', () => {
.get('/subscription-tiers/slug/diamond')
.expect(200)
expect(response.body.basePriceUsd).toBe('299.99')
expect(response.body.basePriceUsd).toBe('799.99')
})
})