Add freemium variant C: archetype persistence, dashboard banner, lesson gate

- User.archetype/utmSource/utmMedium/utmCampaign fields + migration
- register flow reads ?archetype/?utm_* and saves them on the User row
- dashboard ArchetypeBanner: per-archetype 'твой путь' block
- lesson gate after wow-moment lesson (WOW_MOMENT_LESSON_ID=obs-start-l2-006) → tripwire + full-course offer

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-23 11:26:34 +05:00
parent bb6c806cdd
commit 7bf3935c81
12 changed files with 241 additions and 3 deletions
@@ -10,6 +10,7 @@ import { HomeworkSection } from "@/components/student/homework-section";
import { QuizSection } from "@/components/student/quiz-section";
import { LessonComments } from "@/components/student/lesson-comments";
import { FileFormatBadge } from "@/components/shared/file-format-badge";
import { TripwireGateBanner } from "@/components/student/tripwire-gate-banner";
interface Props {
params: Promise<{ slug: string; lessonId: string }>;
@@ -90,6 +91,8 @@ export default async function LessonPage({ params }: Props) {
if (!lesson || lesson.module.course.slug !== slug) notFound();
const isCompleted = !!progress;
const showTripwireGate =
!isAdmin && isCompleted && lessonId === process.env.WOW_MOMENT_LESSON_ID;
// Build ordered flat list of all lessons for prev/next
const allLessons = lesson.module.course.modules.flatMap((m) => m.lessons);
@@ -267,6 +270,8 @@ export default async function LessonPage({ params }: Props) {
)}
</div>
{showTripwireGate && <TripwireGateBanner />}
{/* Comments */}
{session && (
<div