mirror of
https://github.com/Snouzy/workout-cool.git
synced 2026-05-19 14:40:35 +00:00
10efc94827
* feat(premium): implement new pricing page with detailed feature comparison, testimonials, and FAQs to enhance user experience and support mission-driven approach fix(premium): update PremiumManager to return structured plans including Free, Supporter, and Premium options for better clarity and user choice docs(premium): add README for premium UI components detailing architecture, design system, and usage instructions to facilitate development and onboarding * feat(premium): enhance premium features and pricing structure with yearly option and updated UI elements fix(premium): update FAQ content for clarity and accuracy, and remove deprecated features from the comparison table style(premium): improve layout and styling for better user experience across premium upgrade card and feature comparison table * feat(premium): refactor checkout process to retrieve plan details by internal ID and update checkout creation logic chore(premium): remove unused mobile sticky CTA component to streamline codebase fix(pricing): update text for clarity and improve accessibility in various components style(pricing): adjust layout and styling for better responsiveness and visual consistency across pricing sections * chore(premium/ui): remove unused export of MobileStickyCard to clean up codebase * feat(locales): add comprehensive translations for premium features, pricing, and FAQs in English, Spanish, French, Portuguese, Russian, and Chinese to enhance user experience and accessibility across multiple languages refactor(premium UI): implement translation keys for dynamic text rendering in the premium upgrade card, feature comparison table, and pricing FAQ sections to improve maintainability and localization support * chore(pricing-testimonials.tsx): add TODO comment to indicate the need for testimonials implementation * feat(locales): update feature descriptions across multiple languages for clarity and consistency refactor(premium.manager.ts): remove hardcoded free and paid plans to streamline plan management and improve maintainability chore(premium-upgrade-card.tsx): remove deprecated features from the premium upgrade card to reflect current offerings * feat(premium): implement multi-region pricing plans and update environment variables for Stripe price IDs to support various regions fix(premium): update checkout logic to use planId directly instead of fetching plan details refactor(premium): enhance region detection logic for better user experience and add dynamic pricing fetching in the PremiumUpgradeCard component chore(ci): update CI configuration to include new environment variables for multi-region pricing docs: remove outdated error messages from localization files and update premium active state messages for better clarity * fix(seed-subscription-plans): update externalId to use EU-specific environment variables for Stripe pricing plans to ensure correct pricing for the EU region
106 lines
3.4 KiB
TypeScript
106 lines
3.4 KiB
TypeScript
#!/usr/bin/env ts-node
|
|
|
|
import { PrismaClient } from "@prisma/client";
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
async function checkPricingConfig() {
|
|
console.log("🔍 Checking pricing configuration...\n");
|
|
|
|
try {
|
|
// Get all subscription plans
|
|
const plans = await prisma.subscriptionPlan.findMany({
|
|
include: {
|
|
providerMappings: true,
|
|
},
|
|
orderBy: [{ currency: "asc" }, { priceMonthly: "asc" }],
|
|
});
|
|
|
|
console.log(`📊 Found ${plans.length} subscription plans:\n`);
|
|
|
|
// Group by currency
|
|
const plansByCurrency = plans.reduce(
|
|
(acc, plan) => {
|
|
if (!acc[plan.currency]) acc[plan.currency] = [];
|
|
acc[plan.currency].push(plan);
|
|
return acc;
|
|
},
|
|
{} as Record<string, typeof plans>,
|
|
);
|
|
|
|
// Display plans by currency
|
|
for (const [currency, currencyPlans] of Object.entries(plansByCurrency)) {
|
|
console.log(`💰 ${currency} Plans:`);
|
|
console.log("─".repeat(50));
|
|
|
|
for (const plan of currencyPlans) {
|
|
const price = plan.priceMonthly?.toNumber() || plan.priceYearly?.toNumber() || 0;
|
|
const interval = plan.interval;
|
|
const regions = plan.availableRegions.join(", ");
|
|
const mappingsCount = plan.providerMappings.length;
|
|
|
|
console.log(`📌 ${plan.id}`);
|
|
console.log(` Price: ${price} ${currency}/${interval}`);
|
|
console.log(` Regions: ${regions}`);
|
|
console.log(` Active: ${plan.isActive ? "✅" : "❌"}`);
|
|
console.log(` Provider mappings: ${mappingsCount}`);
|
|
|
|
if (plan.providerMappings.length > 0) {
|
|
console.log(" Stripe prices:");
|
|
for (const mapping of plan.providerMappings) {
|
|
console.log(` - ${mapping.region}: ${mapping.externalId} (${mapping.isActive ? "active" : "inactive"})`);
|
|
}
|
|
}
|
|
console.log("");
|
|
}
|
|
}
|
|
|
|
// Check for missing configurations
|
|
console.log("\n⚠️ Configuration checks:");
|
|
console.log("─".repeat(50));
|
|
|
|
const plansWithoutMappings = plans.filter((p) => p.providerMappings.length === 0);
|
|
if (plansWithoutMappings.length > 0) {
|
|
console.log(`❌ ${plansWithoutMappings.length} plans without Stripe mappings:`);
|
|
plansWithoutMappings.forEach((p) => console.log(` - ${p.id}`));
|
|
} else {
|
|
console.log("✅ All plans have Stripe mappings");
|
|
}
|
|
|
|
// Region coverage check
|
|
const regions = ["EU", "US", "UK", "BR", "RU", "CN", "LATAM"];
|
|
const coveredRegions = new Set(plans.flatMap((p) => p.availableRegions));
|
|
const missingRegions = regions.filter((r) => !coveredRegions.has(r));
|
|
|
|
if (missingRegions.length > 0) {
|
|
console.log(`\n❌ Missing coverage for regions: ${missingRegions.join(", ")}`);
|
|
} else {
|
|
console.log("\n✅ All regions have pricing coverage");
|
|
}
|
|
|
|
// Summary
|
|
console.log("\n📈 Summary:");
|
|
console.log("─".repeat(50));
|
|
console.log(`Total plans: ${plans.length}`);
|
|
console.log(`Currencies: ${Object.keys(plansByCurrency).join(", ")}`);
|
|
console.log(`Covered regions: ${Array.from(coveredRegions).join(", ")}`);
|
|
} catch (error) {
|
|
console.error("❌ Error checking pricing config:", error);
|
|
throw error;
|
|
} finally {
|
|
await prisma.$disconnect();
|
|
}
|
|
}
|
|
|
|
// Run if called directly
|
|
if (require.main === module) {
|
|
checkPricingConfig()
|
|
.then(() => process.exit(0))
|
|
.catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|
|
}
|
|
|
|
export default checkPricingConfig;
|