Skip to content
davidthurmanPublic

About

Smart Movie Tracker

Topics

Resources

Stars

10 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

59 Commits

Folders and files

Repository files navigation

MoviQ

MoviQGithubBanner Android Kotlin Min SDK Target SDK

Track your movies. Get AI-powered recommendations. Built with modern Android best practices.

🎬 What is MoviQ?

MoviQ helps you manage your movie watchlist and discover new films using AI. Mark movies as seen, rate your favorites, and let Gemini 2.0 suggest what to watch next based on your taste.

Why this repo exists: I built MoviQ as a reference for Android developers looking for real-world examples of apps using scalable Clean Architecture, Jetpack Compose, Firebase integration, and comprehensive testing. It's the kind of codebase I wish I had when learning modern Android development.

🎬 Track Movies You Watch ❀️ Rate & Mark Your Favorites ✨ Get AI Recs on What to Watch πŸ”Ž Find New Films Tailored to You
Screenshot_20251102_161458-portrait Screenshot_20251102_165001-portrait Screenshot_20251102_162345-portrait Screenshot_20251102_162452-portrait

πŸ—οΈ Architecture

Built with Clean Architecture + MVI Pattern following Google's recommended architecture.

graph LR
    subgraph Presentation["🎨 Presentation Layer"]
        UI[Jetpack Compose UI]
        VM[ViewModels + MVI]
    end
    
    subgraph Domain["βš™οΈ Domain Layer"]
        UC[Use Cases]
        RI[Repository Interfaces]
    end
    
    subgraph Data["πŸ’Ύ Data Layer"]
        REPO[Repository Implementations]
        LOCAL[(Room Database)]
        REMOTE[(Firestore)]
        API[TMDB API]
    end
    
    UI --> VM
    VM --> UC
    UC --> RI
    RI --> REPO
    REPO --> LOCAL
    REPO --> REMOTE
    REPO --> API
    
    style Presentation fill:#e3f2fd,stroke:#1565c0,stroke-width:3px,color:#000
    style Domain fill:#fff3e0,stroke:#ef6c00,stroke-width:3px,color:#000
    style Data fill:#f3e5f5,stroke:#6a1b9a,stroke-width:3px,color:#000
    style UI fill:#bbdefb,stroke:#1565c0,stroke-width:2px,color:#000
    style VM fill:#bbdefb,stroke:#1565c0,stroke-width:2px,color:#000
    style UC fill:#ffe0b2,stroke:#ef6c00,stroke-width:2px,color:#000
    style RI fill:#ffe0b2,stroke:#ef6c00,stroke-width:2px,color:#000
    style REPO fill:#e1bee7,stroke:#6a1b9a,stroke-width:2px,color:#000
    style LOCAL fill:#c5e1a5,stroke:#558b2f,stroke-width:2px,color:#000
    style REMOTE fill:#c5e1a5,stroke:#558b2f,stroke-width:2px,color:#000
    style API fill:#c5e1a5,stroke:#558b2f,stroke-width:2px,color:#000
Loading
Layer Responsibilities Key Technologies
Presentation UI components, ViewModels, state management Jetpack Compose, Material 3, MVI
Domain Business logic, use cases, repository contracts Kotlin, Coroutines, Flow
Data Data sources, repositories, sync logic Room, Firestore, Retrofit, WorkManager
πŸ“‹ Key Architectural Patterns
  • Offline-First: Room as single source of truth with cloud sync
  • Unidirectional Data Flow: MVI pattern with sealed classes
  • Dependency Injection: Hilt for compile-time DI
  • Background Sync: WorkManager with conflict resolution
  • Repository Pattern: Abstract data sources from business logic
  • Use Case Pattern: Single responsibility for each business operation

πŸ› οΈ Tech Stack

Core Android
  • Jetpack Compose - UI
  • Material 3 - Google's Current Design System
  • Hilt - Dependency injection
  • Navigation Compose - Type-safe navigation
  • Lifecycle & ViewModel - State management
  • Additional Features: Cloud sync across devices β€’ Google Sign-In β€’ In-app purchases β€’ Dark mode β€’ Offline-first
Data & Networking
  • Room - Local database (SQLite)
  • Retrofit - REST API client
  • Coil - Image loading & caching
  • DataStore - Preferences storage
  • WorkManager - Background tasks
Firebase Services
  • Authentication - Google Sign-In
  • Firestore - Cloud database
  • Vertex AI - Gemini 2.0 for recommendations
  • Crashlytics - Error tracking
  • Analytics - User insights
Testing
  • JUnit 4 - Unit testing
  • Truth - Assertions
  • Espresso - UI testing
  • Compose Test - Compose UI tests
  • Hilt Testing - DI in tests

πŸ“ Project Structure

Feature-based modularization with clear separation of concerns:

app/src/main/java/com/dthurman/moviesaver/
β”‚
β”œβ”€β”€ 🎯 core/                    # Shared functionality
β”‚   β”œβ”€β”€ app/                    # MainActivity, Navigation, Scaffold
β”‚   β”œβ”€β”€ data/                   # Room DB, sync logic
β”‚   β”œβ”€β”€ domain/                 # Core models (Movie, User)
β”‚   └── observability/          # Analytics & error logging
β”‚
β”œβ”€β”€ 🎬 feature_movies/          # Movie management
β”‚   β”œβ”€β”€ data/                   # TMDB API, Firestore sync
β”‚   β”œβ”€β”€ domain/                 # 8 use cases (search, rate, etc.)
β”‚   └── presentation/           # Discover, Detail, My Movies screens
β”‚
β”œβ”€β”€ πŸ€– feature_ai_recs/         # AI recommendations
β”‚   β”œβ”€β”€ data/                   # Vertex AI integration
β”‚   β”œβ”€β”€ domain/                 # 7 use cases
β”‚   └── presentation/           # Recommendations screen
β”‚
β”œβ”€β”€ πŸ” feature_auth/            # Authentication
β”œβ”€β”€ πŸ’³ feature_billing/         # In-app purchases
└── 🎨 ui/                      # Shared components & theme

πŸ”„ Offline-First Sync Strategy

sequenceDiagram
    participant User
    participant UI
    participant Room
    participant WorkManager
    participant Firestore
    
    User->>UI: Mark movie as seen
    UI->>Room: Update with PENDING_UPDATE
    Room-->>UI: βœ… Instant feedback
    UI->>WorkManager: Trigger sync
    
    Note over WorkManager: Background sync
    WorkManager->>Room: Get pending changes
    Room-->>WorkManager: Movies to sync
    WorkManager->>Firestore: Upload changes
    Firestore-->>WorkManager: βœ… Success
    WorkManager->>Room: Update to SYNCED
Loading

How it works:

  1. User action updates Room immediately (instant UI feedback)
  2. Item marked with sync state
  3. WorkManager syncs to Firestore in background
  4. Conflict resolution uses timestamps (most recent wins)
  5. Periodic sync every 6 hours + on-demand triggers

πŸ€– AI-Powered Recommendations

Uses Firebase Vertex AI (Gemini 2.0 Flash) to analyze your movie history and generate personalized suggestions.

flowchart LR
    A[User's Seen Movies w/ Ratings] --> B[Vertex AI<br/>Gemini 2.0]
    A1[User's Watchlist] --> B
    A2[User's Previously Skipped Recs] --> B
    B --> C[AI Recommendations<br/>with Reasoning]
    C --> D[TMDB API<br/>Validation]
    D --> E{Match Found?}
    E -->|Yes| F[Add to<br/>Recommendations]
    E -->|No| G[Skip]
    F --> H[Display to User]
    
    style B fill:#4285f4,color:#fff
    style F fill:#34a853,color:#fff
    style G fill:#ea4335,color:#fff
Loading

Process:

  1. Analyzes your seen movies + ratings
  2. Sends structured prompt to Gemini 2.0
  3. AI returns 5 movie suggestions with reasoning
  4. Validates against TMDB API
  5. Filters duplicates and already-seen movies

Requirements: Minimum 5 seen movies β€’ 1 credit per generation


πŸ§ͺ Testing

Comprehensive test coverage with 50+ tests across unit, integration, and E2E.

Test Type Framework Count Coverage
Unit Tests JUnit + Truth 30+ Use cases, ViewModels
UI Tests Compose Test + Espresso 15+ Screen interactions
E2E Tests Hilt Testing 5+ Complete user flows

Testing Strategy:

  • Fake repositories for isolation
  • Hilt test modules for DI
  • Coroutines test for async operations
  • Custom HiltTestRunner for instrumented tests
Example Test
@HiltAndroidTest
@UninstallModules(AppModule::class)
class MoviesEndToEndTest {
    @get:Rule(order = 0)
    val hiltRule = HiltAndroidRule(this)
    
    @get:Rule(order = 1)
    val composeRule = createAndroidComposeRule<MainActivity>()
    
    @Test
    fun userCanSearchAndAddMovieToWatchlist() {
        // Complete user flow test
    }
}

πŸš€ Getting Started

Prerequisites

Quick Setup

  1. Clone & Configure

    git clone https://github.com/yourusername/movie-saver.git
    cd movie-saver
  2. Add local.properties

    MOVIES_API_KEY=your_tmdb_api_key
  3. Add Firebase

    • Download google-services.json from Firebase Console
    • Place in app/ directory
    • Enable: Authentication (Google), Firestore, Vertex AI, Crashlytics
  4. Build

    ./gradlew assembleDebug
Detailed Firebase Setup
  • Create Firebase project
  • Add Android app with package name: com.dthurman.moviesaver
  • Enable services:
    • Authentication β†’ Google Sign-In provider
    • Firestore Database β†’ Production mode
    • Vertex AI β†’ Enable Gemini API
    • Crashlytics & Analytics
  • Add SHA-1 fingerprint:
    ./gradlew signingReport
  • Download and add google-services.json

πŸ’‘ Key Highlights

For Developers

  • Production-ready architecture
  • 100% Kotlin & Compose
  • Comprehensive testing examples
  • Modern Android best practices
  • Real-world Firebase integration
  • Clean code with SOLID principles

Technical Achievements

  • Offline-first with sync
  • AI integration (Vertex AI)
  • In-app billing implementation
  • Background processing
  • Type-safe navigation
  • Material 3 theming

🀝 Contributing

This is a reference project, but contributions are welcome! Feel free to open issues or submit PRs.

πŸ“ License

MIT License - see LICENSE file for details.

Built by David Thurman

GitHub β€’ LinkedIn

⭐ Star this repo if you find it helpful!

About

Smart Movie Tracker

Topics

Resources

Stars

10 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages