Mock Data Migration Plan

Document Status: Planning Created: 2025-12-09 Last Updated: 2025-12-09

Executive Summary

This document catalogs all hardcoded mock data in the Momentum codebase and provides a comprehensive migration plan to replace them with real data sources. The goal is to transition from static mock data to dynamic, database-driven content while maintaining application stability.


Table of Contents

  1. Mock Data Inventory
  2. Dependencies Analysis
  3. Migration Phases
  4. Implementation Details
  5. Testing Strategy
  6. Rollback Plan

Mock Data Inventory

Frontend Mock Data Files

File Purpose Lines Status
frontend/data/mockCourses.ts Course catalog with 9 courses ~150 Active - Production
frontend/data/mockUserData.ts User profile “Alex Rivera” ~60 Potentially Orphaned
frontend/data/mockCourseDetails.ts Extended course info (reviews, instructor) ~200 Active - Production
frontend/data/mockLessons.ts Lesson content (hardcoded text) ~650 Active - Production
frontend/lib/api/mock-admin-analytics.ts Admin analytics dashboard data ~230 Active - Dev Fallback
frontend/lib/services/mock-payment-service.ts Stripe payment simulation ~150 Active - Production

Pages Using Mock Data

Page Mock Import Impact
/app/courses/page.tsx mockCourses, categories, durations Course listing blocked
/app/courses/[id]/page.tsx mockCourses Static params, metadata
/app/courses/[id]/CourseDetailPageClient.tsx getCourseDetail() Course details fallback
/app/courses/[id]/lessons/[lessonId]/page.tsx mockCourses, getLessonDetail() Lesson content blocked
/app/courses/[id]/enrollment/success/EnrollmentSuccessClient.tsx mockCourses Success page display
/app/checkout/[sessionId]/CheckoutClient.tsx mock-payment-service Payment flow blocked
/lib/api/admin-analytics.ts mock-admin-analytics Analytics fallback

Mock Data Details

1. mockCourses.ts

Location: frontend/data/mockCourses.ts

Content:

// 9 hardcoded courses with IDs 1-9
export const mockCourses = [
  {
    id: "1",
    title: "Digital Minimalism Mastery",
    description: "...",
    category: "personal-development",
    duration: 7,
    lessons: 7,
    students: 1234,
    rating: 4.8,
    imageUrl: "..."
  },
  // ... 8 more courses
];

export const categories = [...]; // Category list
export const durations = [...];  // Duration options

Real Data Source:

  • API Endpoint: GET /courses
  • Database Table: courses joined with categories
  • Additional: Enrollment counts from enrollments table

Consumers:

  • frontend/app/courses/page.tsx:8 - Main course listing
  • frontend/app/courses/[id]/page.tsx:2,21 - Static params & metadata
  • frontend/app/courses/[id]/lessons/[lessonId]/page.tsx:4 - Lesson static params
  • frontend/app/courses/[id]/enrollment/success/EnrollmentSuccessClient.tsx:13 - Success page

2. mockCourseDetails.ts

Location: frontend/data/mockCourseDetails.ts

Content:

// TODO: Replace with API call when backend is ready (Line 6)
const courseDetails = {
  "1": {
    reviews: 234,
    instructor: { name: "...", title: "...", avatar: "..." },
    whatYouWillLearn: [...],
    curriculum: [{ week: 1, lessons: [...] }]
  },
  "2": { ... }
};

export function getCourseDetail(courseId: string) {
  // Merges mockCourses with detailed data
}

Real Data Source:

  • API Endpoint: GET /courses/{id} (enhanced response)
  • Database Tables: courses with columns what_you_will_learn, instructor (JSONB)
  • Note: Schema already supports these fields (migration 004)

Consumers:

  • frontend/app/courses/[id]/CourseDetailPageClient.tsx:7 - Course detail page

3. mockLessons.ts

Location: frontend/data/mockLessons.ts

Content:

// TODO: Replace with CMS or database when backend is ready (Line 5)
export function getLessonDetail(courseId: string, lessonId: string) {
  return {
    day: parseInt(lessonId),
    title: "Eliminating Digital Distractions",
    duration: "15 minutes",
    content: "...", // ~500 lines of markdown content
    actionItems: [...],
    keyTakeaways: [...],
    resources: [...],
    videoUrl: "...",
    hasQuiz: false,
    nextLesson: { day, title },
    prevLesson: { day, title }
  };
}

Critical Issue: Returns the SAME hardcoded content for ALL lessons regardless of courseId/lessonId.

Real Data Source:

  • API Endpoint: GET /lessons/{id} or GET /courses/{courseId}/lessons/{lessonId}
  • Database Table: lessons with content, action_items, resources columns
  • Additional: Navigation requires adjacent lesson queries

Consumers:

  • frontend/app/courses/[id]/lessons/[lessonId]/page.tsx:5,24 - Lesson viewer

4. mock-payment-service.ts

Location: frontend/lib/services/mock-payment-service.ts

Content:

// Mock Payment Service
// Simulates Stripe payment flow for development
// Will be replaced with real Stripe integration later

export function createMockCheckoutSession(courseId, courseTitle, price) { ... }
export function processMockPayment(sessionId, paymentDetails) { ... }
export function getMockCheckoutSession(sessionId) { ... }
export function createFreeEnrollment(courseId) { ... }
export function validateMockCardDetails(cardDetails) { ... }

Real Data Source:

  • Service: Stripe Checkout API
  • Backend: POST /payments/create-checkout-session
  • Webhook: Stripe webhook → Lambda → enrollment creation

Consumers:

  • frontend/app/checkout/[sessionId]/CheckoutClient.tsx:16,80-94
  • frontend/components/enrollment/EnrollButton.tsx

5. mock-admin-analytics.ts

Location: frontend/lib/api/mock-admin-analytics.ts

Content:

export const mockAnalyticsData = {
  overview: { totalUsers: 1234, revenue: 123400, ... },
  users: { newUsers: 89, activeUsers: 456, ... },
  courses: { totalCourses: 24, ... },
  revenue: { daily: [...], byCourse: [...] },
  engagement: { totalHours: 4567, ... },
  comparison: { ... }
};

Real Data Source:

  • API Endpoint: GET /analytics/platform-stats
  • Database Tables: daily_platform_stats, course_performance_stats, aggregated queries
  • Note: Tables already exist (migration 005)

Consumers:

  • frontend/lib/api/admin-analytics.ts:28-48 - Fallback when API unavailable

6. mockUserData.ts

Location: frontend/data/mockUserData.ts

Status: Potentially orphaned - requires usage verification

Content:

export const mockUserData = {
  name: "Alex Rivera",
  avatar: "...",
  currentStreak: 12,
  totalCoursesCompleted: 5,
  // ... more stats
};

Real Data Source:

  • API Endpoint: GET /users/me or GET /badges/me
  • Database Tables: users, user_statistics

Dependencies Analysis

Database Dependencies

Mock Data Required Tables Migration Status
mockCourses courses, categories, enrollments Tables exist
mockCourseDetails courses (JSONB fields) Schema exists (migration 004)
mockLessons lessons Table exists
mock-payment payments, enrollments Tables exist
mock-analytics daily_platform_stats, course_performance_stats Tables exist (migration 005)
mockUserData users, user_statistics Tables exist

API Dependencies

Mock Data Required Endpoint Implementation Status
mockCourses GET /courses Exists - enhance response
mockCourseDetails GET /courses/{id} Exists - add instructor/curriculum
mockLessons GET /lessons/{id} Exists - verify response shape
mock-payment POST /payments/checkout Not implemented
mock-analytics GET /analytics/* Exists - verify completeness
mockUserData GET /users/me Exists - add statistics

Frontend Dependencies

Course Listing Page
└── mockCourses.ts
    ├── categories (filtering)
    ├── durations (filtering)
    └── course objects (display)

Course Detail Page
├── mockCourses.ts (basic info + static params)
└── mockCourseDetails.ts (extended info)
    ├── instructor
    ├── whatYouWillLearn
    └── curriculum

Lesson Page
├── mockCourses.ts (static params + navigation)
└── mockLessons.ts (content)
    ├── content (markdown)
    ├── actionItems
    ├── resources
    └── navigation (prev/next)

Checkout Flow
└── mock-payment-service.ts
    ├── createMockCheckoutSession
    ├── processMockPayment
    └── validateMockCardDetails

Admin Analytics
└── mock-admin-analytics.ts (dev fallback)
    └── Full analytics dataset

Migration Phases

Phase 1: Course Catalog (Priority: Critical)

Objective: Replace mockCourses.ts with real API data

Tasks:

  1. Enhance Course API Response (backend/functions/courses)
    • Add students_count (enrollment count)
    • Add rating (if implementing ratings) or remove from UI
    • Ensure thumbnail URL is properly formatted
    • Return category object with name and slug
  2. Create Course List Hook (frontend/hooks/useCourses.ts)
    export function useCourses(filters?: CourseFilters) {
      // Fetch from GET /courses with query params
      // Handle loading, error states
      // Support category and duration filtering
    }
    
  3. Update Course List Page (frontend/app/courses/page.tsx)
    • Replace mockCourses import with useCourses hook
    • Fetch categories from API or use cached list
    • Implement proper loading skeleton
    • Handle empty states
  4. Migrate Static Params (frontend/app/courses/[id]/page.tsx)
    • Option A: Switch to dynamic rendering (export const dynamic = 'force-dynamic')
    • Option B: Fetch course IDs at build time from API
    • Option C: Use ISR (Incremental Static Regeneration)

Estimated Scope: 3-4 files, ~200 lines changed


Phase 2: Lesson Content (Priority: Critical)

Objective: Replace mockLessons.ts with real lesson API data

Tasks:

  1. Verify Lesson API Response (backend/functions/lessons)
    • Ensure content field contains full markdown
    • Verify action_items and resources JSONB structure
    • Add estimated_duration_minutes to response
    • Include prev/next lesson navigation data
  2. Create Lesson Hook (frontend/hooks/useLesson.ts)
    export function useLesson(courseId: string, lessonId: string) {
      // Fetch lesson with navigation context
      // Parse and validate response
    }
    
  3. Update Lesson Page (frontend/app/courses/[id]/lessons/[lessonId]/page.tsx)
    • Convert to client component or use server component with API fetch
    • Replace getLessonDetail() with real API call
    • Handle loading and error states
  4. Seed Real Lesson Content
    • Either through admin UI or database seeding
    • Ensure each lesson has unique, meaningful content

Estimated Scope: 2-3 files, ~150 lines changed


Phase 3: Course Details Enhancement (Priority: High)

Objective: Replace mockCourseDetails.ts with enhanced course API

Tasks:

  1. Enhance Course Detail API
    • Return instructor JSONB field
    • Return what_you_will_learn array
    • Return requirements array
    • Include curriculum (lessons grouped by week/section)
  2. Update Course Detail Page (frontend/app/courses/[id]/CourseDetailPageClient.tsx)
    • Remove getCourseDetail() import
    • Use enhanced course API response
    • Remove mock data fallback logic

Estimated Scope: 2 files, ~100 lines changed


Phase 4: Payment Integration (Priority: High)

Objective: Replace mock-payment-service.ts with Stripe Checkout

Tasks:

  1. Implement Payment Backend
    • Create POST /payments/create-checkout-session endpoint
    • Implement Stripe webhook handler
    • Create payment success/failure handling
  2. Create Payment Service (frontend/lib/services/payment-service.ts)
    export async function createCheckoutSession(courseId: string) {
      // Call backend to create Stripe session
      // Return Stripe checkout URL
    }
    
  3. Update Checkout Flow
    • Replace mock functions with real Stripe redirect
    • Update success page to verify payment
    • Handle payment failures gracefully
  4. Environment Setup
    • Add Stripe keys to AWS Secrets Manager
    • Configure webhook endpoints
    • Test with Stripe test mode

Estimated Scope: 5+ files, ~300 lines changed, Stripe account setup


Phase 5: Analytics Real Data (Priority: Medium)

Objective: Ensure admin analytics uses real aggregated data

Tasks:

  1. Verify Analytics Backend
    • Confirm GET /analytics/platform-stats returns complete data
    • Verify daily aggregation job is running
    • Check data accuracy against database
  2. Remove Mock Fallback
    • Update frontend/lib/api/admin-analytics.ts
    • Remove shouldUseMockData() function
    • Always fetch from real API
  3. Handle Edge Cases
    • Empty data (new installation)
    • Partial data (some metrics unavailable)
    • Error states

Estimated Scope: 1-2 files, ~50 lines changed


Phase 6: Cleanup (Priority: Low)

Objective: Remove all mock data files and unused code

Tasks:

  1. Verify No Remaining Usages
    • Search codebase for mock imports
    • Check for indirect dependencies
  2. Delete Mock Files
    • frontend/data/mockCourses.ts
    • frontend/data/mockUserData.ts
    • frontend/data/mockCourseDetails.ts
    • frontend/data/mockLessons.ts
    • frontend/lib/api/mock-admin-analytics.ts
    • frontend/lib/services/mock-payment-service.ts
  3. Clean Up Data Directory
    • Remove frontend/data/ if empty
    • Update any documentation references

Estimated Scope: Delete 6 files, update imports


Implementation Details

Phase 1 Implementation: Course Catalog

Step 1.1: Enhance Backend Course Response

File: backend/functions/courses/src/handlers/get-courses.ts

// Add to course query
const coursesWithStats = await db.query(`
  SELECT
    c.*,
    cat.name as category_name,
    cat.slug as category_slug,
    COUNT(DISTINCT e.id) as students_count,
    COUNT(DISTINCT l.id) as lessons_count
  FROM courses c
  LEFT JOIN categories cat ON c.category_id = cat.id
  LEFT JOIN enrollments e ON c.id = e.course_id
  LEFT JOIN lessons l ON c.id = l.course_id
  WHERE c.status = 'PUBLISHED'
  GROUP BY c.id, cat.id
  ORDER BY c.created_at DESC
`);

Step 1.2: Create Frontend Hook

File: frontend/hooks/useCourses.ts

import { useState, useEffect } from 'react';
import { apiClient } from '@/lib/api/api-client';
import { Course } from '@/lib/api/api-types';

interface CourseFilters {
  category?: string;
  duration?: number;
  search?: string;
}

export function useCourses(filters?: CourseFilters) {
  const [courses, setCourses] = useState<Course[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    async function fetchCourses() {
      try {
        setLoading(true);
        const params = new URLSearchParams();
        if (filters?.category) params.set('category', filters.category);
        if (filters?.duration) params.set('duration', filters.duration.toString());

        const response = await apiClient.get<Course[]>(`/courses?${params}`);
        setCourses(response);
      } catch (err) {
        setError(err as Error);
      } finally {
        setLoading(false);
      }
    }
    fetchCourses();
  }, [filters?.category, filters?.duration]);

  return { courses, loading, error };
}

Step 1.3: Update Course List Page

File: frontend/app/courses/page.tsx

'use client';

import { useCourses } from '@/hooks/useCourses';
import { useCategories } from '@/hooks/useCategories';
import CourseCard from '@/components/courses/CourseCard';
import CourseFilters from '@/components/courses/CourseFilters';

export default function CoursesPage() {
  const [filters, setFilters] = useState({});
  const { courses, loading, error } = useCourses(filters);
  const { categories } = useCategories();

  if (loading) return <CourseListSkeleton />;
  if (error) return <ErrorState error={error} />;
  if (courses.length === 0) return <EmptyState />;

  return (
    <div>
      <CourseFilters
        categories={categories}
        onFilterChange={setFilters}
      />
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
        {courses.map(course => (
          <CourseCard key={course.id} course={course} />
        ))}
      </div>
    </div>
  );
}

Testing Strategy

Unit Tests

  • Test API client functions with mocked responses
  • Test hooks with React Testing Library
  • Verify data transformation functions

Integration Tests

  • Test full page render with API mocks
  • Verify filter functionality
  • Test error handling paths

E2E Tests

  • Course browsing flow
  • Enrollment flow (with test Stripe)
  • Lesson navigation
  • Admin analytics access

Data Validation

  • Verify database has sufficient seed data
  • Check all courses have lessons
  • Validate instructor and curriculum data populated

Rollback Plan

Per-Phase Rollback

Each phase can be rolled back independently:

  1. Revert Git Commits - Each phase should be a separate PR
  2. Feature Flags - Consider adding flags for gradual rollout
  3. Mock Data Preserved - Keep mock files until Phase 6 complete

Emergency Rollback

If production issues occur:

# Revert to last known good state
git revert <commit-hash>

# Re-enable mock data imports (if removed)
# Update import paths in affected files

Data Backup

  • Database snapshots before each deployment
  • Keep mock data files in git history
  • Document any manual data migrations

Success Criteria

Phase Completion Checklist

  • All tests passing
  • No TypeScript errors
  • No console errors in browser
  • Page load times acceptable (<2s)
  • Mobile responsive maintained
  • No broken images or links
  • Admin functionality working
  • Analytics data accurate

Final Migration Complete When

  • All mock data files deleted
  • No references to mock data in codebase
  • All pages fetching from real APIs
  • Payment processing working with Stripe
  • Documentation updated
  • Team trained on content management

Appendix: File References

Files to Modify

frontend/app/courses/page.tsx
frontend/app/courses/[id]/page.tsx
frontend/app/courses/[id]/CourseDetailPageClient.tsx
frontend/app/courses/[id]/lessons/[lessonId]/page.tsx
frontend/app/courses/[id]/enrollment/success/EnrollmentSuccessClient.tsx
frontend/app/checkout/[sessionId]/CheckoutClient.tsx
frontend/lib/api/admin-analytics.ts

Files to Create

frontend/hooks/useCourses.ts
frontend/hooks/useLesson.ts
frontend/hooks/useCategories.ts
frontend/lib/services/payment-service.ts (replace mock)

Files to Delete (Phase 6)

frontend/data/mockCourses.ts
frontend/data/mockUserData.ts
frontend/data/mockCourseDetails.ts
frontend/data/mockLessons.ts
frontend/lib/api/mock-admin-analytics.ts
frontend/lib/services/mock-payment-service.ts


Back to top

Momentum LMS © 2025. Distributed under the MIT license.