Skip to content

Demo Flutter e-commerce app showcasing clean architecture, BLoC, and feature-based structure.

Notifications You must be signed in to change notification settings

bernesdev/flutly-store

Repository files navigation

Logo

Flutly Store

Tests Flutter Architecture

Flutly is a demo e-commerce mobile application built with Flutter to showcase clean architecture, feature-based organization, and production-ready patterns.

⚠️ This app is for demonstration purposes only. No real payments, orders, or transactions are processed.

Flutly Store

πŸ“‘ Table of Contents

✨ Overview

Flutly simulates a complete shopping experience, including authentication, product browsing, cart management, and checkout.

The project is structured to reflect real-world mobile applications, prioritizing:

  • Feature-based organization
  • Clear separation of concerns
  • Scalable navigation and state management
  • Maintainable and testable architecture

πŸ“Έ Screenshots

Home Screen Product Details Search Screen Shopping Cart Shopping Cart

πŸ“± Key Features

  • Authentication: Email/password and social sign-in.
  • Dynamic Content: Home integrated with Sanity CMS.
  • Product Catalog: Search, filtering, and product details.
  • Cart & Checkout: Local state management with mocked checkout flow.
  • Feedback Loop: Built-in bug reporting flow.

πŸ§ͺ Try the App (Closed Test)

You can install the Flutly app directly on your device via the closed test builds.

πŸ‘‰ Flutly – Closed Test Page

🧱 Tech Stack

  • Flutter & Dart
  • State management: flutter_bloc
  • Navigation: go_router
  • Dependency injection: get_it
  • Networking: dio
  • Local storage: shared_preferences, flutter_secure_storage
  • Forms: reactive_forms
  • Localization: easy_localization
  • Backend Services: Firebase (Auth, Firestore, Analytics) & Sanity CMS.

πŸ— Architecture

Flutly follows a feature-first Clean Architecture approach.

graph TD
    subgraph Presentation ["<b>Presentation Layer</b>"]
        UI[Pages & Widgets]
        State[BLoC / Cubit]
    end

    subgraph Domain ["<b>Domain Layer</b>"]
        UC[Use Cases]
        RC[Repository Interfaces]
        E[Entities]
    end

    subgraph Data ["<b>Data Layer</b>"]
        RI[Repository Implementation]
        DS[Data Sources]
        M[Data Models]
    end

    subgraph Ext ["Firebase / Sanity / DummyJSON"]
    end

    subgraph Lo ["Local Storage"]
    end

    %% Request
    UI --> State
    State --> UC
    State -->  RC
    UC --> RC
    RI --> RC

    %% Response
    Ext --> DS
    Lo --> DS
    DS --> M
    M --> RI
    RI .-> E
Loading

πŸ—‚οΈ Folder Structure

Each feature (e.g., auth, catalog, checkout) is self-contained:

lib/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ core/           # Routing, DI, HttpClient, Storage
β”‚   β”œβ”€β”€ shared/         # Common Widgets, Theme, Extensions
β”‚   └── features/
β”‚       β”œβ”€β”€ auth/       # Feature: Authentication
β”‚       β”œβ”€β”€ catalog/    # Feature: Product Browsing
β”‚       β”œβ”€β”€ cart/       # Feature: Shopping Cart
β”‚       └── ...
β”œβ”€β”€ main.dart
└── firebase_options.dart

πŸ’‘ Technical Decisions

Why BLoC?

I chose flutter_bloc for its strict separation of presentation and business logic. It provides a predictable state stream, making it easier to trace bugs and write unit tests for every user interaction.

The "Demo Mode"

To make this portfolio project easy to run for recruiters and developers, I implemented a Demo Mode.

  • Challenge: The app needed to function fully without requiring valid Firebase credentials.
  • Solution: Based on environment variables, the Dependency Injection (GetIt) swaps the real Firebase implementations for Mock implementations at runtime. This ensures the UI code remains completely agnostic of the data source.

πŸš€ Getting Started

Prerequisites

  • Flutter SDK (sdk: ^3.9.2)
  • Android Studio or Xcode
  • CocoaPods (for iOS)

Configuration

Environment variables

Environment values are provided via --dart-define. The project includes an env.example.json file preconfigured to run without any backend setup.

⚑ Demo Mode (Recommended)

By default, Flutly runs in demo mode. No Firebase project or credentials are needed. Authentication is simulated, and data is handled locally.

  1. Create the env file:
cp env.example.json env.prod.json
  1. Run the app:
flutter run --dart-define-from-file=env.prod.json

πŸ”₯ Firebase Mode

To enable real backend integration:

  1. Open env.prod.json and set:
"USE_FIREBASE": true
  1. Create a Firebase project (Auth + Firestore enabled).

  2. Add configuration files (google-services.json / GoogleService-Info.plist).

  3. Reconfigure via FlutterFire:

flutterfire configure
  1. Run the app:
flutter run --dart-define-from-file=env.prod.json

Installation

# Install dependencies
flutter pub get

# iOS setup
cd ios && pod install

πŸ§ͺ Running the Tests

The project prioritizes test coverage for Domain logic, Use Cases, and Repositories.

Unit and Widget Tests

flutter test

Test Coverage

To generate coverage data and HTML report:

flutter test --coverage
genhtml coverage/lcov.info -o coverage/html

Note: genhtml is part of lcov.

  • macOS: brew install lcov
  • Ubuntu/Debian: sudo apt-get install lcov

Current line coverage: 80%+

Test Coverage

🎨 Assets & Localization

  • Assets: assets/icons, assets/images
  • Localization: Handled via easy_localization (Current locale: en).

πŸ‘¨β€πŸ’» Author

Gabriel Peres Bernes Mobile Software Engineer β€” Flutter Specialist

LinkedIn: https://www.linkedin.com/in/gabriel-peres-bernes/

Email: bernes.dev@gmail.com

πŸ“„ License & Disclaimer

This project is intended for educational and demonstration purposes only and does not represent a real commercial product.

About

Demo Flutter e-commerce app showcasing clean architecture, BLoC, and feature-based structure.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages