A full-stack learning application with "Resume where you left off" functionality, built with Flutter (Frontend) and Go (Backend) with MongoDB database.
- Features
- Tech Stack
- Architecture
- Prerequisites
- Installation
- Running the Application
- API Documentation
- Project Structure
- Design Decisions
- Edge Cases Handled
- Future Improvements
- Resume Video Playback: Automatically resume videos from the exact timestamp where you left off
- Resume Quiz Progress: Continue quizzes from the exact question you were on
- Cross-Device Synchronization: Login from any device and pick up exactly where you left off
- Auto-Save Progress: Progress is automatically saved every 5 seconds during video playback
- Real-time Progress Tracking: See your completion percentage for each chapter
- Professional UI/UX: Clean, modern interface with smooth animations
- Simple login/logout system
- User progress visualization
- Chapter completion tracking
- Quiz scoring and results
- Continue card showing most recent activity
- Progress reset functionality
- Flutter: Cross-platform mobile framework
- Provider: State management
- Chewie: Video player with controls
- Shared Preferences: Local storage
- Go (Golang): High-performance backend API
- Gorilla Mux: HTTP router
- MongoDB: NoSQL database for flexible data storage
- Docker: Containerization
- Docker Compose: Multi-container orchestration
┌─────────────┐
│ Flutter │ (Mobile App)
│ Frontend │
└──────┬──────┘
│ HTTP REST API
│
┌──────▼──────┐
│ Go │ (Backend Server)
│ Backend │
└──────┬──────┘
│ MongoDB Driver
│
┌──────▼──────┐
│ MongoDB │ (Database)
└─────────────┘
- User interacts with Flutter UI
- Flutter app makes HTTP requests to Go backend
- Go backend processes requests and interacts with MongoDB
- MongoDB stores/retrieves user data and progress
- Backend sends response back to Flutter
- Flutter updates UI based on response
- Go 1.21 or higher
- Docker & Docker Compose (recommended) OR
- MongoDB 7.0+ (if running without Docker)
- Flutter SDK 3.0.0 or higher
- Android Studio / Xcode (for emulators)
- Android SDK (for Android)
- iOS SDK (for iOS)
git clone <repository-url>
cd resume-learning-appcd backend
docker-compose up -dThis will start both MongoDB and the Go backend server.
-
Install MongoDB locally and ensure it's running on port 27017
-
Install Go dependencies:
cd backend
go mod download- Run the backend:
go run main.goThe backend will be available at http://localhost:8080
cd frontend
flutter pub getOpen lib/services/api_service.dart and update the baseUrl:
// For Android emulator
static const String baseUrl = 'http://10.0.2.2:8080/api';
// For iOS simulator
static const String baseUrl = 'http://localhost:8080/api';
// For physical device (replace with your computer's IP)
static const String baseUrl = 'http://192.168.1.XXX:8080/api';cd backend
docker-compose up
# OR if running manually
go run main.goThe backend will start on http://localhost:8080
cd frontend
# For Android
flutter run
# For iOS
flutter run
# For specific device
flutter devices # List available devices
flutter run -d <device-id>http://localhost:8080/api
GET /api/healthResponse:
{
"success": true,
"message": "Server is running",
"data": {
"status": "healthy",
"time": "2025-01-01T00:00:00Z"
}
}POST /api/login
Content-Type: application/json
{
"userId": "user123",
"name": "John Doe"
}Response:
{
"success": true,
"message": "Login successful",
"user": {
"id": "...",
"userId": "user123",
"name": "John Doe",
"createdAt": "...",
"updatedAt": "..."
}
}GET /api/chaptersResponse:
{
"success": true,
"message": "Chapters fetched successfully",
"data": [
{
"id": "...",
"chapterId": "chapter_1",
"title": "Introduction to Programming",
"description": "...",
"videoUrl": "...",
"duration": 596,
"quiz": {
"questions": [...]
},
"order": 1
}
]
}GET /api/progress/{userId}Response:
{
"success": true,
"progress": [
{
"id": "...",
"userId": "user123",
"chapterId": "chapter_1",
"videoProgress": 120,
"videoCompleted": false,
"quizProgress": 2,
"quizAnswers": [0, 2, -1, -1, -1],
"quizCompleted": false,
"chapterCompleted": false,
"lastAccessedAt": "...",
"updatedAt": "..."
}
]
}POST /api/progress/video
Content-Type: application/json
{
"userId": "user123",
"chapterId": "chapter_1",
"progress": 120,
"completed": false
}POST /api/progress/quiz
Content-Type: application/json
{
"userId": "user123",
"chapterId": "chapter_1",
"questionIndex": 2,
"answer": 1,
"completed": false
}DELETE /api/progress/{userId}/resetLearningApp/
├── backend/
│ ├── main.go # Main backend application
│ ├── go.mod # Go dependencies
│ ├── Dockerfile # Docker configuration
│ ├── docker-compose.yml # Docker Compose setup
│ └── .env.example # Environment variables template
│
└── frontend/
├── lib/
│ ├── main.dart # App entry point
│ ├── models/ # Data models
│ │ ├── user.dart
│ │ ├── chapter.dart
│ │ └── progress.dart
│ ├── providers/ # State management
│ │ └── app_provider.dart
│ ├── screens/ # UI screens
│ │ ├── login_screen.dart
│ │ ├── home_screen.dart
│ │ ├── video_player_screen.dart
│ │ └── quiz_screen.dart
│ ├── services/ # API & Storage services
│ │ ├── api_service.dart
│ │ └── storage_service.dart
│ ├── widgets/ # Reusable widgets
│ │ ├── chapter_card.dart
│ │ └── continue_card.dart
│ └── utils/ # Utilities & constants
│ └── app_colors.dart
└── pubspec.yaml # Flutter dependencies
- Video progress is saved every 5 seconds while playing
- Quiz progress is saved immediately after each answer
- Prevents data loss if app crashes or user exits unexpectedly
- Video: Resumes from exact second using
VideoPlayerController.seekTo() - Quiz: Restores question index and previous answers
- Backend stores timestamp and question index separately
- Used Provider for simplicity and efficiency
- Single AppProvider manages global app state
- Local state for screen-specific UI
- Pull-based synchronization: App fetches latest data on startup
- Push-based updates: Progress is pushed to server immediately
- Cross-device support: Same user ID works across all devices
- Loading indicators for async operations
- Error handling with user-friendly messages
- Offline-first approach with local storage backup
- Progress visualization with percentage and status
- Separate collections for Users, Chapters, Progress
- Compound index on (userId, chapterId) for fast progress lookup
- Upsert operations to handle create/update in one call
- No progress exists → Returns empty progress
- Starts from beginning (video: 0 seconds, quiz: question 0)
- Progress synced from database
- Latest progress displayed on new device
- Detects when video reaches end
- Marks video as completed
- Enables quiz access
- Saves answer for each question immediately
- Can navigate back/forward between questions
- Resumes at exact question on return
- Graceful error handling with retry options
- Local storage fallback for user credentials
- Error messages guide user to resolution
- Last-write-wins strategy
- MongoDB upsert prevents duplicate records
- Timestamp tracks latest update
- Input validation on both frontend and backend
- Required field checks
- Data type validation
- Error detection and user notification
- Fallback UI with retry option
- Handles network video loading failures
- Login as user "test1"
- Start Chapter 1 video
- Watch for 30 seconds
- Close app
- Reopen app and login as "test1"
- Open Chapter 1
- ✅ Video should resume at 30 seconds
- Login as user "test2"
- Complete Chapter 1 video
- Start quiz and answer 2 questions
- Close app
- Reopen and login as "test2"
- Open Chapter 1 quiz
- ✅ Should resume at question 3
- Login as "test3" on Device A
- Watch video until 1:00
- Login as "test3" on Device B
- ✅ Video shows progress at 1:00
- Login as "user1", make progress
- Logout and login as "user2"
- ✅ "user2" starts from scratch
- Logout and login back as "user1"
- ✅ "user1" sees their previous progress
- User profiles with avatars
- Bookmarking specific video timestamps
- Notes and highlights
- Downloadable certificates
- Social features (share progress, leaderboards)
- Content recommendations
- Offline video downloads
- Multiple video quality options
- Subtitle support
- WebSocket for real-time updates
- JWT authentication
- Redis caching layer
- Video streaming optimization
- Analytics and tracking
- Unit and integration tests
- CI/CD pipeline
- Performance monitoring
- Rate limiting
- API versioning
- Dark mode
- Accessibility improvements
- Animations and transitions
- Onboarding tutorial
- In-app notifications
- Search functionality
- Filtering and sorting
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License.
Note: This is an assignment project showcasing full-stack development skills with Flutter, Go, and MongoDB.