Skip to content

deveminsahin/starter_app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

199 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Flutter Enterprise Starter

coverage CI style: very good analysis License: MIT Flutter Dart

An AI-ready, enterprise-grade Flutter starter app built with Clean Architecture, Domain-Driven Design (DDD), Hexagonal Architecture, and 100% test coverage.

Demo

Light Mode Dark Mode


✨ What Makes This Different

Feature Description
πŸ€– AI-Ready Architecture 23 architecture rules for AI-assisted development
πŸ§ͺ 100% Test Coverage Comprehensive tests across all layers
πŸ—οΈ CQRS Pattern Separate Commands (write) and Queries (read)
πŸ” Type-Safe Routing go_router_builder with compile-time route safety
βš™οΈ Environment Config --dart-define-from-file for secure configuration
🧱 Mason Bricks Code generators for consistent feature scaffolding
πŸ“± Adaptive UI Material 3 canonical layouts with 5-class breakpoint system
πŸ”„ Token Refresh Automatic 401 handling with thread-safe refresh
πŸ›‘οΈ Security Secure storage, certificate pinning, code obfuscation
🌐 Feature-First i18n ARB files per feature with gen_l10n
β™Ώ Accessibility WCAG 2.1 compliant with semantic labels
πŸ“Š Structured Logging IAppLogger with environment-specific outputs

πŸ›οΈ Architecture Overview

This project follows Hexagonal Architecture (Ports & Adapters) with DDD tactical patterns:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                              PRESENTATION                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚   Pages     β”‚  β”‚   Widgets   β”‚  β”‚    BLoC     β”‚  β”‚   Routes    β”‚        β”‚
β”‚  β”‚  (Views)    β”‚  β”‚ (Reusable)  β”‚  β”‚ (State Mgmt)β”‚  β”‚ (Type-Safe) β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                              APPLICATION                                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚  Commands   β”‚  β”‚   Queries   β”‚  β”‚  Use Cases  β”‚  β”‚   Events    β”‚        β”‚
β”‚  β”‚ (Write Ops) β”‚  β”‚ (Read Ops)  β”‚  β”‚ (Orchestr.) β”‚  β”‚ (Domain)    β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                DOMAIN                                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚  Entities   β”‚  β”‚Value Objectsβ”‚  β”‚    Ports    β”‚  β”‚   Failures  β”‚        β”‚
β”‚  β”‚ (Identity)  β”‚  β”‚(Validation) β”‚  β”‚ (Interfaces)β”‚  β”‚ (Either<>)  β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                            INFRASTRUCTURE                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚  β”‚Repositories β”‚  β”‚Data Sources β”‚  β”‚   Chopper   β”‚  β”‚   Secure    β”‚        β”‚
β”‚  β”‚ (Adapters)  β”‚  β”‚ (Remote/DB) β”‚  β”‚ (HTTP/WS)   β”‚  β”‚  Storage    β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Core Patterns

Pattern Implementation
CQRS Commands for writes, Queries for reads
Railway-Oriented Either<Failure, T> with fpdart
Hexagonal Ports (interfaces) & Adapters (implementations)
Type-Safe Routing @TypedGoRoute with go_router_builder
Interceptor Chain Auth β†’ Refresh β†’ Logging β†’ Error (Chopper)
Adaptive Navigation Bottom nav, Rail, or Drawer based on screen size

Included Features

Feature Description
πŸ” Authentication Login, Register, Token refresh, Logout with secure storage
πŸ“Š Dashboard Home screen with adaptive navigation (Bar/Rail/Drawer)
πŸ‘€ Profile User profile management
πŸ“¦ Orders Order management and history
βš™οΈ Settings Theme & locale switching with HydratedBloc persistence
🚩 Feature Flags Runtime feature toggles without third-party services
πŸ”Œ WebSocket Real-time communication with auto-reconnect
🌐 API Client Chopper with Auth, Refresh, Logging, Error interceptors

πŸš€ Getting Started

Prerequisites

  • Flutter 3.41.2 (stable)
  • Dart 3.11.0
  • Very Good CLI: dart pub global activate very_good_cli

Quick Start

# 1. Clone and install
git clone https://github.com/deveminsahin/starter_app.git
cd starter_app
very_good packages get

# 2. Run code generation
dart run build_runner build --delete-conflicting-outputs

# 3. Run tests
very_good test --coverage

# 4. Launch app
flutter run \
  --flavor development \
  --target lib/main_development.dart \
  --dart-define-from-file=config/development.json

βš™οΈ Environment Configuration

This project uses --dart-define-from-file for secure, type-safe environment configuration:

config/
β”œβ”€β”€ development.json.example   # Copy and remove .example
β”œβ”€β”€ staging.json.example       # Copy and remove .example
β”œβ”€β”€ production.json.example    # Copy and remove .example
└── example.json               # Template reference

Important

First-time setup: Copy the .example files and remove the .example suffix:

cd config
cp development.json.example development.json
cp staging.json.example staging.json
cp production.json.example production.json

Running with Environment Config

# Development
flutter run \
  --flavor development \
  --target lib/main_development.dart \
  --dart-define-from-file=config/development.json

# Staging
flutter run \
  --flavor staging \
  --target lib/main_staging.dart \
  --dart-define-from-file=config/staging.json

# Production
flutter run \
  --flavor production \
  --target lib/main_production.dart \
  --dart-define-from-file=config/production.json

VS Code Launch Config

Pre-configured in .vscode/launch.json for one-click debugging.


πŸ—ΊοΈ Type-Safe Navigation

Routes are fully type-safe using go_router_builder:

// Navigate with compile-time safety
const AuthRoute().go(context);
const DashboardRoute().go(context);

// Route definition (features/auth/presentation/routes/auth_routes.dart)
@TypedGoRoute<AuthRoute>(
  path: RouteDefinitions.authPath,
  name: RouteDefinitions.authName,
)
class AuthRoute extends BaseRoute with $AuthRoute {
  const AuthRoute();

  @override
  Widget build(BuildContext context, GoRouterState state) {
    return const AuthPage();
  }
}

Route Architecture

  • Centralized definitions: core/navigation/route_definitions.dart
  • Feature-owned routes: Each feature declares its routes via part of
  • Custom transitions: Shared page transitions in base_route.dart
  • Adaptive navigation: Bottom nav, rail, or drawer based on screen size

πŸ§ͺ Testing

100% test coverage with comprehensive tests across all layers. Uses Very Good CLI for proper coverage reporting.

# Run all tests with coverage
very_good test --coverage

# Run specific test file
very_good test test/features/auth/application/usecases/login_test.dart

# Generate HTML coverage report
genhtml coverage/lcov.info -o coverage/html
open coverage/html/index.html

# Update golden files
very_good test --update-goldens

Test Types

Type Location Purpose
Unit test/ Domain logic, use cases, repositories
Widget test/ UI components with pumpApp helper
BLoC test/ State management with bloc_test
Golden test/goldens/ Visual regression screenshots
Property-Based test/ Fuzz testing with Glados
Benchmark test/benchmarks/ Performance metrics
Integration integration_test/ Full user flows

πŸ“ Project Structure

lib/
β”œβ”€β”€ app/                    # App entry point, providers
β”œβ”€β”€ core/                   # Shared infrastructure
β”‚   β”œβ”€β”€ api/               # Chopper HTTP client, interceptors
β”‚   β”œβ”€β”€ application/       # Bootstrap, environment
β”‚   β”œβ”€β”€ di/                # Dependency injection (get_it + injectable)
β”‚   β”œβ”€β”€ domain/            # Base classes (Entity, ValueObject)
β”‚   β”œβ”€β”€ error/             # Failure types, exception handling
β”‚   β”œβ”€β”€ feature_flags/     # Runtime feature toggles
β”‚   β”œβ”€β”€ infrastructure/    # Base repositories, WebSocket
β”‚   β”œβ”€β”€ l10n/              # Localization (gen_l10n)
β”‚   β”œβ”€β”€ navigation/        # GoRouter, type-safe routes
β”‚   β”œβ”€β”€ presentation/      # Shared widgets, failure messages
β”‚   └── theme/             # Material 3, flex_color_scheme
└── features/              # Business domain features
    β”œβ”€β”€ auth/              # Authentication (reference implementation)
    β”œβ”€β”€ dashboard/         # Home with adaptive navigation
    β”œβ”€β”€ orders/            # Order management
    β”œβ”€β”€ profile/           # User profile management
    └── settings/          # Theme & locale switching

πŸ€– AI-Ready Development

This project includes 23 architecture rule files in docs/architecture-rules/ for AI-assisted development:

Category Rules
Core Architecture Project structure, layers, domain, application, infrastructure, presentation
Patterns State management, error handling, DI, navigation, data modeling
Quality Testing, code quality, accessibility, theming
Integration API integration, i18n, security, logging, performance

AI tools can understand and generate architecture-compliant code using these rules.


οΏ½ Mason Bricks

Generate architecture-compliant code with Mason:

# Install Mason CLI
dart pub global activate mason_cli

# Generate a new feature
mason make feature --feature_name payments

# Generate a use case
mason make use_case --name get_payment_history

# Available bricks: feature, use_case, bloc, entity, value_object, repository

See MASON_GUIDE.md for detailed templates.


πŸ“¦ Tech Stack

Core

Package Purpose
flutter_bloc State management
go_router + go_router_builder Type-safe navigation
get_it + injectable Dependency injection
fpdart Functional error handling
freezed Immutable data classes

Infrastructure

Package Purpose
chopper HTTP client with code generation
flutter_secure_storage Secure token storage
hydrated_bloc Persistent state
flex_color_scheme Material 3 theming
synchronized Thread-safe locks (token refresh)

Quality

Package Purpose
very_good_analysis Strict linting
bloc_test BLoC testing utilities
mocktail Mocking framework
glados Property-based testing

πŸ“– Documentation

Document Description
ARCHITECTURE.md System design and patterns
CONTRIBUTING.md Development guidelines
CHANGELOG.md Version history
MASON_GUIDE.md Code generation templates
docs/adr/ Architecture Decision Records

πŸ”Œ Backend (Optional)

Want to test with a real backend? A companion Spring Boot server is available:

πŸ‘‰ starter_app_backend

# Option 1: Run with Docker
git clone https://github.com/deveminsahin/starter_app_backend.git
cd starter_app_backend
docker-compose up

# Option 2: Run directly (requires Java 25+)
./gradlew bootRun

Backend runs at http://localhost:8080. The Flutter app is pre-configured to connect.

Backend Features

Feature Endpoint Description
πŸ” Authentication /api/v1/auth/* Register, Login, Refresh, Logout
πŸ‘€ Profile /api/v1/profiles/* Create, Read, Update profile
πŸ”„ WebSocket /ws/auth Real-time auth state notifications

Note

The backend uses an in-memory H2 database for development. All data resets on restart.


β˜• Support

If you find this project useful, consider supporting its development:

Buy Me A Coffee

🀝 Contributing

See CONTRIBUTING.md for development setup, code style, and PR guidelines.


πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


Releases

No releases published

Packages

 
 
 

Contributors