Skip to content

Latest commit

 

History

History
419 lines (336 loc) · 11.1 KB

File metadata and controls

419 lines (336 loc) · 11.1 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a Flutter-based mobile application for learning AI and Data Science. The app features:

  • Gamified learning experience (XP, levels, streaks, achievements)
  • AI-generated educational content via local LLMs
  • Duolingo-inspired UI/UX
  • Comprehensive learning path from beginner to expert
  • Full offline support with local storage

Target Platform: iOS (Android-ready architecture)

Essential Commands

Setup and Installation

# Install Flutter dependencies
flutter pub get

# Generate code for Hive adapters and Riverpod
flutter pub run build_runner build --delete-conflicting-outputs

# Clean generated files
flutter pub run build_runner clean

Running the App

# Run on iOS simulator (default)
flutter run

# Run on specific simulator
flutter run -d "iPhone 14 Pro"

# Run on physical device
flutter run -d <device-id>

# Run in release mode
flutter run --release

Development

# Hot reload: Press 'r' while app is running
# Hot restart: Press 'R' while app is running
# Quit: Press 'q'

# Format code
flutter format .

# Analyze code
flutter analyze

# List devices
flutter devices

Testing

# Run all tests
flutter test

# Run with coverage
flutter test --coverage

# Run specific test file
flutter test test/models/user_progress_test.dart

Building

# Build iOS release
flutter build ios --release

# Build iOS debug
flutter build ios --debug

# Clean build artifacts
flutter clean

AI Content Generation (Optional)

# Start Ollama server (in separate terminal)
ollama serve

# Pull AI model
ollama pull llama3.2

# Test Ollama connection
curl http://localhost:11434/api/generate -d '{"model":"llama3.2","prompt":"test"}'

Architecture Overview

State Management: Riverpod

The app uses Riverpod 2.0+ for state management:

  • Providers are in lib/providers/
  • Notifiers extend StateNotifier<T>
  • Use ConsumerWidget or Consumer to watch providers
  • Use ref.watch() for reactive updates
  • Use ref.read() for one-time access

Key provider:

  • userProgressProvider: Main user progress state

Data Persistence: Hive + SharedPreferences

  • Hive: Complex objects (UserProgress, cached lessons)
  • SharedPreferences: Simple settings
  • Adapters: Generated via build_runner (see *.g.dart files)
  • Storage Service: Centralized API in lib/services/storage_service.dart

Navigation

  • Uses named routes defined in main.dart
  • Main routes: /, /onboarding, /home, /learning-path, /lesson, /profile, /achievements
  • Pass arguments via Navigator.pushNamed(context, '/lesson', arguments: {'lessonId': id})

Theme System

  • Centralized in lib/utils/app_theme.dart
  • Duolingo-inspired color palette
  • Google Fonts: Poppins (headings), Inter (body)
  • Material 3 design system

Project Structure

lib/
├── main.dart                       # App entry, routes, providers
├── models/                         # Data structures
│   ├── user_progress.dart         # User stats, XP, streaks
│   ├── lesson.dart                # Lesson structure
│   ├── learning_module.dart       # Module organization
│   └── achievement.dart           # Achievement system
├── providers/                      # Riverpod state
│   └── user_progress_provider.dart
├── screens/                        # Full-screen views
│   ├── splash_screen.dart
│   ├── onboarding_screen.dart
│   ├── home_screen.dart
│   ├── learning_path_screen.dart
│   ├── lesson_screen.dart
│   ├── profile_screen.dart
│   └── achievements_screen.dart
├── widgets/                        # Reusable components
│   ├── stat_card.dart
│   ├── streak_widget.dart
│   ├── daily_goal_widget.dart
│   └── module_card.dart
├── services/                       # Business logic
│   ├── ai_content_service.dart    # LLM integration
│   ├── storage_service.dart       # Data persistence
│   └── notification_service.dart  # Push notifications
├── data/                           # Static content
│   └── learning_content.dart      # Pre-generated lessons
└── utils/                          # Helpers
    └── app_theme.dart

Key Concepts

Gamification System

  • XP: Users earn experience points for completing lessons
  • Levels: Every 100 XP unlocks a new level
  • Streaks: Daily learning maintains fire streak
  • Achievements: Unlocked by milestones (streaks, XP, lessons)
  • Daily Goals: Customizable daily XP targets

Content Structure

  • Modules: High-level topics (e.g., "Python Basics")
  • Lessons: Individual learning units within modules
  • Lesson Types: Tutorial, Practice, Quiz, Project, Reading
  • Difficulty Levels: Beginner, Intermediate, Advanced, Expert

AI Content Generation

  • Uses Ollama for local LLM inference
  • Falls back to template content if AI unavailable
  • Can generate: lessons, quizzes, code examples, explanations
  • Configured in AIContentService class

Development Guidelines

Adding a New Screen

  1. Create file in lib/screens/
  2. Extend StatelessWidget or StatefulWidget
  3. Add route in main.dart routes map
  4. Navigate with Navigator.pushNamed(context, '/route-name')

Adding a New Widget

  1. Create file in lib/widgets/
  2. Make it reusable with required parameters
  3. Use const constructors when possible
  4. Follow existing widget patterns

Adding a New Model

  1. Create file in lib/models/
  2. For Hive storage:
    • Add @HiveType(typeId: X) annotation
    • Add @HiveField(Y) for each field
    • Add part 'model_name.g.dart';
    • Run code generation
  3. For simple models: extend Equatable for easy equality

Modifying User Progress

Always use the provider:

// In a ConsumerWidget
ref.read(userProgressProvider.notifier).addXP(50);
ref.read(userProgressProvider.notifier).completeLesson('lesson_id', 20);
ref.read(userProgressProvider.notifier).updateStreak();

Adding New Content

  1. Edit lib/data/learning_content.dart
  2. Add modules, lessons, questions following existing patterns
  3. Use AI service for dynamic generation
  4. Test content rendering in lesson viewer

Common Tasks

Generating New Lessons with AI

final aiService = AIContentService();
final lesson = await aiService.generateLesson(
  moduleId: 'my_module',
  topic: 'Python Functions',
  difficulty: DifficultyLevel.beginner,
  type: LessonType.tutorial,
);

Tracking Lesson Completion

await StorageService.completeLesson('lesson_id', xpReward: 20);
// This automatically:
// - Marks lesson as complete
// - Awards XP
// - Checks for level up
// - Triggers notifications if needed

Adding Achievements

  1. Add to LearningContent.getAllAchievements() in learning_content.dart
  2. Check conditions in appropriate places
  3. Unlock via: ref.read(userProgressProvider.notifier).unlockAchievement('achievement_id')

Code Generation

This project uses build_runner for:

  • Hive adapters: *.g.dart files for model persistence
  • Riverpod generators: Future use with riverpod_generator

Important: After modifying models with @HiveType annotations, run:

flutter pub run build_runner build --delete-conflicting-outputs

Styling Guidelines

Colors

Use AppTheme constants:

  • AppTheme.primaryGreen - Success, primary actions
  • AppTheme.primaryBlue - Info, secondary
  • AppTheme.primaryPurple - Premium
  • AppTheme.primaryYellow - Rewards
  • AppTheme.primaryOrange - Streaks

Typography

Use theme text styles:

Theme.of(context).textTheme.displayLarge
Theme.of(context).textTheme.headlineMedium
Theme.of(context).textTheme.bodyLarge

Spacing

Use consistent spacing (multiples of 4):

  • Small: 8px
  • Medium: 16px
  • Large: 24px
  • Extra Large: 32px

Testing Strategy

Unit Tests

  • Test model logic (XP calculation, level progression)
  • Test service methods (storage, AI generation)
  • Test utility functions

Widget Tests

  • Test widget rendering
  • Test user interactions
  • Test state changes

Integration Tests

  • Test user flows (onboarding, lesson completion)
  • Test data persistence
  • Test gamification triggers

Performance Tips

  1. Use const constructors wherever possible
  2. Minimize rebuilds: Watch specific providers, not entire state
  3. Lazy load: Don't load all lessons at once
  4. Cache images: Use CachedNetworkImage
  5. Profile regularly: Use Flutter DevTools

Troubleshooting

Build Runner Issues

flutter clean
rm -rf .dart_tool
flutter pub get
flutter pub run build_runner build --delete-conflicting-outputs

iOS Build Issues

cd ios
pod deintegrate
pod install
cd ..
flutter clean
flutter run

State Not Updating

  • Ensure using ConsumerWidget or Consumer
  • Use ref.watch() not ref.read() for reactive updates
  • Check if StateNotifier is calling state = newState

AI Service Connection Failed

  • Verify Ollama is running: ollama serve
  • Check model is downloaded: ollama list
  • Test endpoint: curl http://localhost:11434/api/tags
  • App will use fallback content if AI unavailable

Dependencies Overview

Core

  • flutter: Framework
  • flutter_riverpod: State management
  • hive, hive_flutter: Local storage
  • shared_preferences: Simple key-value storage

UI/UX

  • google_fonts: Typography
  • flutter_animate: Animations
  • lottie: Complex animations
  • shimmer: Loading states

Features

  • flutter_local_notifications: Push notifications
  • flutter_highlighting: Code syntax highlighting
  • fl_chart: Data visualization
  • cached_network_image: Image caching

Development

  • build_runner: Code generation
  • hive_generator: Generate adapters
  • flutter_lints: Linting rules

File Naming Conventions

  • Screens: *_screen.dart
  • Widgets: *_widget.dart or descriptive name
  • Services: *_service.dart
  • Providers: *_provider.dart
  • Models: descriptive name
  • Use snake_case for files

Important Notes

  1. Always run code generation after model changes
  2. Test on real device for accurate performance
  3. Use Riverpod DevTools for debugging state
  4. Check memory usage when adding animations
  5. Profile before optimizing - measure first!

Resources

Quick Reference

Adding XP

ref.read(userProgressProvider.notifier).addXP(50);

Checking Completion

final progress = ref.watch(userProgressProvider);
final isCompleted = progress?.hasCompletedLesson('lesson_id') ?? false;

Navigation

Navigator.pushNamed(context, '/lesson', arguments: {'lessonId': 'id'});

Storage

await StorageService.saveLesson('id', lessonData);
final lesson = StorageService.getLesson('id');

For detailed information, see:

  • Setup: SETUP_GUIDE.md
  • Development: DEVELOPMENT.md
  • Overview: PROJECT_SUMMARY.md