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
- Mock Data Inventory
- Dependencies Analysis
- Migration Phases
- Implementation Details
- Testing Strategy
- 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:
coursesjoined withcategories - Additional: Enrollment counts from
enrollmentstable
Consumers:
frontend/app/courses/page.tsx:8- Main course listingfrontend/app/courses/[id]/page.tsx:2,21- Static params & metadatafrontend/app/courses/[id]/lessons/[lessonId]/page.tsx:4- Lesson static paramsfrontend/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:
courseswith columnswhat_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}orGET /courses/{courseId}/lessons/{lessonId} - Database Table:
lessonswithcontent,action_items,resourcescolumns - 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-94frontend/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/meorGET /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:
- Enhance Course API Response (
backend/functions/courses)- Add
students_count(enrollment count) - Add
rating(if implementing ratings) or remove from UI - Ensure
thumbnailURL is properly formatted - Return
categoryobject with name and slug
- Add
- 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 } - Update Course List Page (
frontend/app/courses/page.tsx)- Replace
mockCoursesimport withuseCourseshook - Fetch categories from API or use cached list
- Implement proper loading skeleton
- Handle empty states
- Replace
- 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)
- Option A: Switch to dynamic rendering (
Estimated Scope: 3-4 files, ~200 lines changed
Phase 2: Lesson Content (Priority: Critical)
Objective: Replace mockLessons.ts with real lesson API data
Tasks:
- Verify Lesson API Response (
backend/functions/lessons)- Ensure
contentfield contains full markdown - Verify
action_itemsandresourcesJSONB structure - Add
estimated_duration_minutesto response - Include prev/next lesson navigation data
- Ensure
- Create Lesson Hook (
frontend/hooks/useLesson.ts)export function useLesson(courseId: string, lessonId: string) { // Fetch lesson with navigation context // Parse and validate response } - 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
- 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:
- Enhance Course Detail API
- Return
instructorJSONB field - Return
what_you_will_learnarray - Return
requirementsarray - Include curriculum (lessons grouped by week/section)
- Return
- Update Course Detail Page (
frontend/app/courses/[id]/CourseDetailPageClient.tsx)- Remove
getCourseDetail()import - Use enhanced course API response
- Remove mock data fallback logic
- Remove
Estimated Scope: 2 files, ~100 lines changed
Phase 4: Payment Integration (Priority: High)
Objective: Replace mock-payment-service.ts with Stripe Checkout
Tasks:
- Implement Payment Backend
- Create
POST /payments/create-checkout-sessionendpoint - Implement Stripe webhook handler
- Create payment success/failure handling
- Create
- 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 } - Update Checkout Flow
- Replace mock functions with real Stripe redirect
- Update success page to verify payment
- Handle payment failures gracefully
- 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:
- Verify Analytics Backend
- Confirm
GET /analytics/platform-statsreturns complete data - Verify daily aggregation job is running
- Check data accuracy against database
- Confirm
- Remove Mock Fallback
- Update
frontend/lib/api/admin-analytics.ts - Remove
shouldUseMockData()function - Always fetch from real API
- Update
- 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:
- Verify No Remaining Usages
- Search codebase for mock imports
- Check for indirect dependencies
- Delete Mock Files
frontend/data/mockCourses.tsfrontend/data/mockUserData.tsfrontend/data/mockCourseDetails.tsfrontend/data/mockLessons.tsfrontend/lib/api/mock-admin-analytics.tsfrontend/lib/services/mock-payment-service.ts
- Clean Up Data Directory
- Remove
frontend/data/if empty - Update any documentation references
- Remove
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:
- Revert Git Commits - Each phase should be a separate PR
- Feature Flags - Consider adding flags for gradual rollout
- 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