BAB 34. FOLDER STRUCTURE FLUTTER
Pendekatan
Menggunakan Clean Architecture + Riverpod + Feature First untuk memastikan kode terorganisir, mudah diuji, dan dapat dikerjakan oleh tim secara paralel.
Struktur Utama
lib/
├── app/ # Konfigurasi aplikasi
├── core/ # Utilitas dan layanan inti
├── features/ # Semua fitur terpisah
├── shared/ # Komponen yang dipakai bersama
└── main.dart # Entry point
Detail Setiap Folder
app/ — Konfigurasi Aplikasi
app/
├── router/ # GoRouter route definitions
│ └── app_router.dart
├── theme/ # Color, typography, spacing tokens
│ └── app_theme.dart
├── config/ # API base URL, environment
│ └── app_config.dart
└── app.dart # Root widget & ProviderScope
core/ — Layanan Inti
core/
├── network/ # HTTP client (Dio + interceptors)
│ ├── api_client.dart
│ └── auth_interceptor.dart
├── storage/ # Flutter Secure Storage wrapper
│ └── secure_storage.dart
├── error/ # Exception & failure classes
│ ├── exceptions.dart
│ └── failures.dart
├── utils/ # Date, format, validation helpers
│ └── helpers.dart
├── constants/ # App-wide constants
│ └── app_constants.dart
├── services/ # GPS, QR, FCM service
│ ├── gps_service.dart
│ ├── qr_service.dart
│ └── fcm_service.dart
└── widgets/ # Shared base widgets
├── app_button.dart
├── app_text_field.dart
└── loading_overlay.dart
features/ — Fitur Aplikasi
features/
├── auth/
├── dashboard/
├── profile/
├── request/
├── matching/
├── booking/
├── chat/
├── meeting/
├── rating/
├── leaderboard/
├── notification/
└── teacher/
Struktur Internal Setiap Feature
Setiap feature mengikuti pola 4 layer yang konsisten:
features/request/
├── data/ # Layer implementasi data
│ ├── datasource/ # Remote & local data sources
│ │ └── request_remote_datasource.dart
│ ├── repository/ # Implementasi repository
│ │ └── request_repository_impl.dart
│ ├── dto/ # Data Transfer Objects (JSON mapping)
│ │ └── request_dto.dart
│ └── models/ # Raw model dari API
│ └── request_model.dart
│
├── domain/ # Layer bisnis (pure Dart, no Flutter)
│ ├── entities/ # Objek bisnis inti
│ │ └── request_entity.dart
│ ├── repositories/ # Interface/contract repository
│ │ └── request_repository.dart
│ └── usecases/ # Use case per aksi
│ ├── create_request.dart
│ ├── get_requests.dart
│ └── cancel_request.dart
│
├── presentation/ # Layer UI (Flutter widgets)
│ ├── pages/ # Halaman penuh
│ │ ├── request_list_page.dart
│ │ └── create_request_page.dart
│ ├── widgets/ # Widget khusus feature ini
│ │ └── request_card.dart
│ └── controllers/ # StateNotifier/ViewModel
│ └── request_controller.dart
│
└── providers/ # Riverpod providers
└── request_providers.dart
shared/ — Komponen Bersama
shared/
├── widgets/ # Widget yang dipakai banyak feature
│ ├── user_avatar.dart
│ ├── badge_chip.dart
│ └── empty_state.dart
├── models/ # Model yang dipakai lintas feature
│ └── pagination_model.dart
└── extensions/ # Dart extensions
├── context_extension.dart
└── string_extension.dart
Keuntungan Arsitektur
| Keuntungan | Penjelasan |
|---|---|
| Modular | Setiap feature berdiri sendiri |
| Mudah diuji | Domain layer adalah pure Dart |
| Scalable | Mudah tambah feature baru |
| Tim paralel | Satu tim per feature |
| Konsisten | Pola yang sama di semua feature |
Dependency Flow
flowchart TD
P["📱 Presentation\n(Pages, Widgets)"] --> UC["⚙️ Domain\n(Use Cases, Entities)"]
UC --> RI["📋 Repository\nInterface"]
RI --> R["🗄️ Data\n(Repository Impl, Datasource)"]
R --> API["🌐 API / Network"]
style P fill:#4f63d2,color:#fff
style UC fill:#7c3aed,color:#fff
style R fill:#059669,color:#fff
style API fill:#1f2937,color:#fff
:::important Aturan Dependency Layer dalam (Domain) tidak boleh bergantung pada layer luar (Data/Presentation). Ketergantungan hanya boleh dari luar ke dalam. :::