refactor(config): cadence-keyed plan id, add getTierAmount, drop per-tier helcimPlanId
This commit is contained in:
parent
35197c465b
commit
be0e6e7699
3 changed files with 64 additions and 159 deletions
|
|
@ -1,82 +1,22 @@
|
||||||
// Central configuration for Ghost Guild Contribution Levels and Helcim Plans
|
// Central configuration for Ghost Guild Contribution Levels
|
||||||
export const CONTRIBUTION_TIERS = {
|
export const CONTRIBUTION_TIERS = {
|
||||||
FREE: {
|
FREE: { value: "0", amount: 0, label: "$0 - I need support right now", tier: "free" },
|
||||||
value: "0",
|
SUPPORTER: { value: "5", amount: 5, label: "$5 - I can contribute", tier: "supporter" },
|
||||||
amount: 0,
|
MEMBER: { value: "15", amount: 15, label: "$15 - I can sustain the community", tier: "member" },
|
||||||
label: "$0 - I need support right now",
|
ADVOCATE: { value: "30", amount: 30, label: "$30 - I can support others too", tier: "advocate" },
|
||||||
tier: "free",
|
CHAMPION: { value: "50", amount: 50, label: "$50 - I want to sponsor multiple members", tier: "champion" },
|
||||||
helcimPlanId: null, // No Helcim plan needed for free tier
|
}
|
||||||
},
|
|
||||||
SUPPORTER: {
|
|
||||||
value: "5",
|
|
||||||
amount: 5,
|
|
||||||
label: "$5 - I can contribute",
|
|
||||||
tier: "supporter",
|
|
||||||
helcimPlanId: "supporter-monthly-5",
|
|
||||||
},
|
|
||||||
MEMBER: {
|
|
||||||
value: "15",
|
|
||||||
amount: 15,
|
|
||||||
label: "$15 - I can sustain the community",
|
|
||||||
tier: "member",
|
|
||||||
helcimPlanId: "member-monthly-15",
|
|
||||||
},
|
|
||||||
ADVOCATE: {
|
|
||||||
value: "30",
|
|
||||||
amount: 30,
|
|
||||||
label: "$30 - I can support others too",
|
|
||||||
tier: "advocate",
|
|
||||||
helcimPlanId: "advocate-monthly-30",
|
|
||||||
},
|
|
||||||
CHAMPION: {
|
|
||||||
value: "50",
|
|
||||||
amount: 50,
|
|
||||||
label: "$50 - I want to sponsor multiple members",
|
|
||||||
tier: "champion",
|
|
||||||
helcimPlanId: "champion-monthly-50",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get all contribution options as an array (useful for forms)
|
export const getContributionOptions = () => Object.values(CONTRIBUTION_TIERS)
|
||||||
export const getContributionOptions = () => {
|
export const getValidContributionValues = () => Object.values(CONTRIBUTION_TIERS).map(t => t.value)
|
||||||
return Object.values(CONTRIBUTION_TIERS);
|
export const getContributionTierByValue = (value) =>
|
||||||
};
|
Object.values(CONTRIBUTION_TIERS).find(t => t.value === value)
|
||||||
|
export const requiresPayment = (value) => (getContributionTierByValue(value)?.amount ?? 0) > 0
|
||||||
|
export const isValidContributionValue = (value) => getValidContributionValues().includes(value)
|
||||||
|
export const getPaidContributionTiers = () =>
|
||||||
|
Object.values(CONTRIBUTION_TIERS).filter(t => t.amount > 0)
|
||||||
|
|
||||||
// Get valid contribution values for validation
|
export function getTierAmount(tier, cadence = 'monthly') {
|
||||||
export const getValidContributionValues = () => {
|
const base = parseFloat(tier.amount)
|
||||||
return Object.values(CONTRIBUTION_TIERS).map((tier) => tier.value);
|
return cadence === 'annual' ? base * 10 : base
|
||||||
};
|
}
|
||||||
|
|
||||||
// Get contribution tier by value
|
|
||||||
export const getContributionTierByValue = (value) => {
|
|
||||||
return Object.values(CONTRIBUTION_TIERS).find((tier) => tier.value === value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get Helcim plan ID for a contribution tier
|
|
||||||
export const getHelcimPlanId = (contributionValue) => {
|
|
||||||
const tier = getContributionTierByValue(contributionValue);
|
|
||||||
return tier?.helcimPlanId || null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if a contribution tier requires payment
|
|
||||||
export const requiresPayment = (contributionValue) => {
|
|
||||||
const tier = getContributionTierByValue(contributionValue);
|
|
||||||
return tier?.amount > 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if a contribution value is valid
|
|
||||||
export const isValidContributionValue = (value) => {
|
|
||||||
return getValidContributionValues().includes(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get contribution tier by Helcim plan ID
|
|
||||||
export const getContributionTierByHelcimPlan = (helcimPlanId) => {
|
|
||||||
return Object.values(CONTRIBUTION_TIERS).find(
|
|
||||||
(tier) => tier.helcimPlanId === helcimPlanId,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get paid tiers only (excluding free tier)
|
|
||||||
export const getPaidContributionTiers = () => {
|
|
||||||
return Object.values(CONTRIBUTION_TIERS).filter((tier) => tier.amount > 0);
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -1,85 +1,30 @@
|
||||||
// Server-side contribution config
|
// Server-side contribution config
|
||||||
// Copy of the client-side config for server use
|
|
||||||
|
|
||||||
// Central configuration for Ghost Guild Contribution Levels and Helcim Plans
|
|
||||||
export const CONTRIBUTION_TIERS = {
|
export const CONTRIBUTION_TIERS = {
|
||||||
FREE: {
|
FREE: { value: "0", amount: 0, label: "$0 - I need support right now", tier: "free" },
|
||||||
value: "0",
|
SUPPORTER: { value: "5", amount: 5, label: "$5 - I can contribute", tier: "supporter" },
|
||||||
amount: 0,
|
MEMBER: { value: "15", amount: 15, label: "$15 - I can sustain the community", tier: "member" },
|
||||||
label: "$0 - I need support right now",
|
ADVOCATE: { value: "30", amount: 30, label: "$30 - I can support others too", tier: "advocate" },
|
||||||
tier: "free",
|
CHAMPION: { value: "50", amount: 50, label: "$50 - I want to sponsor multiple members", tier: "champion" },
|
||||||
helcimPlanId: null, // No Helcim plan needed for free tier
|
}
|
||||||
},
|
|
||||||
SUPPORTER: {
|
|
||||||
value: "5",
|
|
||||||
amount: 5,
|
|
||||||
label: "$5 - I can contribute",
|
|
||||||
tier: "supporter",
|
|
||||||
helcimPlanId: 20162,
|
|
||||||
},
|
|
||||||
MEMBER: {
|
|
||||||
value: "15",
|
|
||||||
amount: 15,
|
|
||||||
label: "$15 - I can sustain the community",
|
|
||||||
tier: "member",
|
|
||||||
helcimPlanId: 21596,
|
|
||||||
},
|
|
||||||
ADVOCATE: {
|
|
||||||
value: "30",
|
|
||||||
amount: 30,
|
|
||||||
label: "$30 - I can support others too",
|
|
||||||
tier: "advocate",
|
|
||||||
helcimPlanId: 21597,
|
|
||||||
},
|
|
||||||
CHAMPION: {
|
|
||||||
value: "50",
|
|
||||||
amount: 50,
|
|
||||||
label: "$50 - I want to sponsor multiple members",
|
|
||||||
tier: "champion",
|
|
||||||
helcimPlanId: 21598,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get all contribution options as an array (useful for forms)
|
export const getContributionOptions = () => Object.values(CONTRIBUTION_TIERS)
|
||||||
export const getContributionOptions = () => {
|
export const getValidContributionValues = () => Object.values(CONTRIBUTION_TIERS).map(t => t.value)
|
||||||
return Object.values(CONTRIBUTION_TIERS);
|
export const getContributionTierByValue = (value) =>
|
||||||
};
|
Object.values(CONTRIBUTION_TIERS).find(t => t.value === value)
|
||||||
|
export const requiresPayment = (value) => (getContributionTierByValue(value)?.amount ?? 0) > 0
|
||||||
|
export const isValidContributionValue = (value) => getValidContributionValues().includes(value)
|
||||||
|
export const getPaidContributionTiers = () =>
|
||||||
|
Object.values(CONTRIBUTION_TIERS).filter(t => t.amount > 0)
|
||||||
|
|
||||||
// Get valid contribution values for validation
|
export function getTierAmount(tier, cadence = 'monthly') {
|
||||||
export const getValidContributionValues = () => {
|
const base = parseFloat(tier.amount)
|
||||||
return Object.values(CONTRIBUTION_TIERS).map((tier) => tier.value);
|
return cadence === 'annual' ? base * 10 : base
|
||||||
};
|
}
|
||||||
|
|
||||||
// Get contribution tier by value
|
// Cadence-keyed plan-id lookup. Throws via createError at call site if env missing;
|
||||||
export const getContributionTierByValue = (value) => {
|
// this helper just returns the raw runtime-config value.
|
||||||
return Object.values(CONTRIBUTION_TIERS).find((tier) => tier.value === value);
|
export function getHelcimPlanId(cadence) {
|
||||||
};
|
const config = useRuntimeConfig()
|
||||||
|
if (cadence === 'annual') return config.helcimAnnualPlanId || null
|
||||||
// Get Helcim plan ID for a contribution tier
|
return config.helcimMonthlyPlanId || null
|
||||||
export const getHelcimPlanId = (contributionValue) => {
|
}
|
||||||
const tier = getContributionTierByValue(contributionValue);
|
|
||||||
return tier?.helcimPlanId || null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if a contribution tier requires payment
|
|
||||||
export const requiresPayment = (contributionValue) => {
|
|
||||||
const tier = getContributionTierByValue(contributionValue);
|
|
||||||
return tier?.amount > 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if a contribution value is valid
|
|
||||||
export const isValidContributionValue = (value) => {
|
|
||||||
return getValidContributionValues().includes(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get contribution tier by Helcim plan ID
|
|
||||||
export const getContributionTierByHelcimPlan = (helcimPlanId) => {
|
|
||||||
return Object.values(CONTRIBUTION_TIERS).find(
|
|
||||||
(tier) => tier.helcimPlanId === helcimPlanId,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get paid tiers only (excluding free tier)
|
|
||||||
export const getPaidContributionTiers = () => {
|
|
||||||
return Object.values(CONTRIBUTION_TIERS).filter((tier) => tier.amount > 0);
|
|
||||||
};
|
|
||||||
|
|
|
||||||
20
tests/server/config/contributions.test.js
Normal file
20
tests/server/config/contributions.test.js
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { describe, it, expect } from 'vitest'
|
||||||
|
import { getTierAmount } from '../../../server/config/contributions.js'
|
||||||
|
|
||||||
|
describe('getTierAmount', () => {
|
||||||
|
it('returns monthly amount as-is', () => {
|
||||||
|
expect(getTierAmount({ amount: 5 }, 'monthly')).toBe(5)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns annual amount as base * 10', () => {
|
||||||
|
expect(getTierAmount({ amount: 5 }, 'annual')).toBe(50)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns annual amount for $50 tier', () => {
|
||||||
|
expect(getTierAmount({ amount: 50 }, 'annual')).toBe(500)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('defaults cadence to monthly', () => {
|
||||||
|
expect(getTierAmount({ amount: 15 })).toBe(15)
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
Add table
Add a link
Reference in a new issue