// Default AI model for all tiers (can override in user settings on PRO) const DEFAULT_AI_MODEL = 'openai/gpt-4o-mini'; // Subscription tier limits export const SUBSCRIPTION_LIMITS = { FREE: { coursesPerMonth: 2, defaultAiModel: DEFAULT_AI_MODEL, }, PREMIUM: { coursesPerMonth: 5, defaultAiModel: DEFAULT_AI_MODEL, }, PRO: { coursesPerMonth: 15, defaultAiModel: DEFAULT_AI_MODEL, }, } as const; // Prices in RUB for Russian locale (approximate) const PRICE_RUB = { FREE: 0, PREMIUM: 999, PRO: 2999, } as const; // Subscription plans for display export const SUBSCRIPTION_PLANS = [ { tier: 'FREE' as const, name: 'Free', nameRu: 'Бесплатный', description: 'Perfect for trying out CourseCraft', descriptionRu: 'Идеально для знакомства с CourseCraft', price: 0, priceRu: PRICE_RUB.FREE, currency: 'USD', features: [ '2 courses per month', 'Basic AI model', 'Standard support', ], featuresRu: [ '2 курса в месяц', 'Базовая нейросеть', 'Стандартная поддержка', ], stripePriceId: null, }, { tier: 'PREMIUM' as const, name: 'Premium', nameRu: 'Премиум', description: 'For creators who need more', descriptionRu: 'Для тех, кому нужно больше', price: 9.99, priceRu: PRICE_RUB.PREMIUM, currency: 'USD', features: [ '5 courses per month', 'Enhanced AI model', 'Priority support', 'Advanced editing tools', ], featuresRu: [ '5 курсов в месяц', 'Улучшенная нейросеть', 'Приоритетная поддержка', 'Расширенные инструменты редактирования', ], stripePriceId: process.env.STRIPE_PRICE_PREMIUM || null, }, { tier: 'PRO' as const, name: 'Pro', nameRu: 'Профессиональный', description: 'For power users and teams', descriptionRu: 'Для профессионалов и команд', price: 29.99, priceRu: PRICE_RUB.PRO, currency: 'USD', features: [ '15 courses per month', 'Best AI model available', 'Priority support 24/7', 'Advanced editing tools', 'Custom AI model selection', 'Export to PDF (coming soon)', ], featuresRu: [ '15 курсов в месяц', 'Лучшая доступная нейросеть', 'Приоритетная поддержка 24/7', 'Расширенные инструменты редактирования', 'Выбор модели нейросети', 'Экспорт в PDF (скоро)', ], stripePriceId: process.env.STRIPE_PRICE_PRO || null, }, ] as const; export type SubscriptionPlan = (typeof SUBSCRIPTION_PLANS)[number]; /** Format plan price for display. Uses RUB when language is Russian. */ export function formatPlanPrice( plan: { price: number; priceRu: number; currency: string }, language: string ): { amount: number; currency: string; formatted: string } { const isRu = language === 'ru' || language.startsWith('ru'); if (isRu) { const amount = plan.priceRu; return { amount, currency: 'RUB', formatted: amount === 0 ? 'Бесплатно' : `${amount.toLocaleString('ru-RU')} ₽`, }; } return { amount: plan.price, currency: plan.currency, formatted: plan.price === 0 ? 'Free' : `$${plan.price}`, }; } // Generation progress steps export const GENERATION_STEPS = { PENDING: { progress: 0, label: 'Waiting to start', labelRu: 'Ожидание запуска' }, ANALYZING: { progress: 10, label: 'Analyzing your request', labelRu: 'Анализ запроса' }, ASKING_QUESTIONS: { progress: 15, label: 'Preparing questions', labelRu: 'Подготовка вопросов' }, WAITING_FOR_ANSWERS: { progress: 20, label: 'Waiting for your answers', labelRu: 'Ожидание ваших ответов' }, RESEARCHING: { progress: 30, label: 'Researching the topic', labelRu: 'Исследование темы' }, GENERATING_OUTLINE: { progress: 50, label: 'Creating course structure', labelRu: 'Создание структуры курса' }, GENERATING_CONTENT: { progress: 70, label: 'Writing course content', labelRu: 'Написание содержания' }, COMPLETED: { progress: 100, label: 'Course completed!', labelRu: 'Курс готов!' }, FAILED: { progress: 0, label: 'Generation failed', labelRu: 'Ошибка генерации' }, CANCELLED: { progress: 0, label: 'Generation cancelled', labelRu: 'Генерация отменена' }, } as const; // API Routes export const API_ROUTES = { AUTH: { ME: '/auth/me', CALLBACK: '/auth/callback', LOGOUT: '/auth/logout', }, USERS: { PROFILE: '/users/profile', SETTINGS: '/users/settings', }, COURSES: { LIST: '/courses', CREATE: '/courses', GET: (id: string) => `/courses/${id}`, UPDATE: (id: string) => `/courses/${id}`, DELETE: (id: string) => `/courses/${id}`, }, CHAPTERS: { LIST: (courseId: string) => `/courses/${courseId}/chapters`, CREATE: (courseId: string) => `/courses/${courseId}/chapters`, UPDATE: (courseId: string, chapterId: string) => `/courses/${courseId}/chapters/${chapterId}`, DELETE: (courseId: string, chapterId: string) => `/courses/${courseId}/chapters/${chapterId}`, REORDER: (courseId: string) => `/courses/${courseId}/chapters/reorder`, }, LESSONS: { GET: (courseId: string, lessonId: string) => `/courses/${courseId}/lessons/${lessonId}`, UPDATE: (courseId: string, lessonId: string) => `/courses/${courseId}/lessons/${lessonId}`, }, GENERATION: { START: '/generation/start', STATUS: (id: string) => `/generation/${id}/status`, ANSWER: (id: string) => `/generation/${id}/answer`, CANCEL: (id: string) => `/generation/${id}/cancel`, }, SUBSCRIPTIONS: { PLANS: '/subscriptions/plans', CURRENT: '/subscriptions/current', CHECKOUT: '/subscriptions/checkout', PORTAL: '/subscriptions/portal', }, SEARCH: { COURSES: '/search/courses', }, } as const; // Validation export const VALIDATION = { COURSE: { TITLE_MIN: 3, TITLE_MAX: 200, DESCRIPTION_MAX: 5000, }, CHAPTER: { TITLE_MIN: 2, TITLE_MAX: 200, }, LESSON: { TITLE_MIN: 2, TITLE_MAX: 200, }, PROMPT: { MIN: 10, MAX: 2000, }, } as const;