## Apskel Owner Flutter

A POS (Point of Sale) application for business owners, built with Flutter. The project follows a layered architecture (presentation → application → domain → infrastructure) with dependency injection, state management, automated routing, internationalization, and code generation.

---

### Contents

- Technical Summary
- Requirements & Setup
- Running the App
- Architecture Overview
- Project Structure
- Key Dependencies & Purpose
- Code Generation (see docs/codegen.md)
- Internationalization (i18n)
- Theming & Assets
- Environment Configuration (`env.dart`)
- Development Practices

---

## Technical Summary

- SDK: Flutter (Material) with Dart ^3.8.1
- Targets: Android, iOS, Web, Desktop (Windows, macOS, Linux)
- State management: `flutter_bloc`
- Routing: `auto_route`
- Dependency Injection: `get_it` + `injectable`
- HTTP Client: `dio` (+ `awesome_dio_interceptor`)
- Data class & serialization: `freezed` + `json_serializable`
- Localization: `flutter_localizations`, `l10n/*.arb`
- Assets generation: `flutter_gen`

---

## Requirements & Setup

### Prerequisites

- Flutter SDK installed as per the official guide (`https://flutter.dev/docs/get-started/install`)
- Dart version per constraint: ^3.8.1
- For code generation only: FVM + Flutter 3.41.9 (`dart pub global activate fvm && fvm install 3.41.9`) — see [docs/codegen.md](docs/codegen.md)

### Installation

```bash
git clone <your-repo-url>
cd apskel_owner_flutter
flutter pub get
```

### Code generation (required after clone or when annotations change)

> **Do not run codegen with Flutter 3.47 / Dart 3.13** — every builder crashes with
> `Missing implementation of visitDotShorthandPropertyAccess`. Codegen must run on Flutter 3.41.9
> (Dart 3.11.5) via FVM. Full setup, commands, and troubleshooting: **[docs/codegen.md](docs/codegen.md)**.

```powershell
$FVM = "$env:USERPROFILE\fvm\versions\3.41.9\bin"

& "$FVM\flutter.bat" pub get
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs
flutter pub get   # restore lockfile resolution for the global SDK
```

> Re-run whenever you change files using `@RoutePage()`, `@injectable`, `@freezed`, or `@JsonSerializable`.

---

## Running the App

```bash
flutter run
```

Select a specific device/platform:

```bash
flutter run -d chrome
flutter run -d ios
flutter run -d android
```

Example release builds:

```bash
flutter build apk --release
flutter build ios --release
flutter build web --release
```

---

## Architecture Overview

The codebase follows a clean, layered approach that separates concerns and keeps features modular and testable:

- Presentation (`lib/presentation`): Widgets, pages/screens, and the `AutoRoute` router. Contains only UI code and wiring to BLoC/Cubit.
- Application (`lib/application`): BLoC/Cubit and application-level orchestration. Holds input validation, state transitions, and calls into the Domain layer.
- Domain (`lib/domain`): Pure business logic. Entities, value objects, repository interfaces, and (optional) use-cases. No framework dependencies.
- Infrastructure (`lib/infrastructure`): Repository implementations, DTOs, and data sources (HTTP/DB). Performs `dio` calls and mappings between DTOs and Domain entities.
- Common (`lib/common`): Cross-cutting helpers such as API base, DI setup, constants, extensions, theme, validators, and utilities.

Data flow in a feature:

1. UI triggers an intent/event in Presentation →
2. Application layer BLoC/Cubit handles the event and calls a repository/use-case from Domain →
3. Infrastructure implements the repository, performs network calls via `dio`, and maps results →
4. Data is converted to Domain entities and returned to Application →
5. Application updates state, Presentation rebuilds UI accordingly.

Cross-cutting concerns:

- Dependency Injection: `get_it` + `injectable` auto-register services/repositories (`injection.dart`, `injection.config.dart`).
- Routing: `auto_route` defines typed routes, generated into router files in `presentation/router`.
- State: `flutter_bloc` models states/events and isolates side-effects in BLoCs/Cubits.
- Networking: `dio` with interceptors for logging and error handling.
- Error handling: functional style with `dartz` (`Either`, `Option`) or well-defined BLoC states.
- i18n: ARB files in `lib/l10n/` and generated localization delegates.
- Theming: centralized theme under `lib/common/theme/` with shared design tokens.
- Assets: managed under `assets/` and referenced via FlutterGen outputs at `lib/presentation/components/assets/`.

---

## Project Structure

```
lib/
  application/           # BLoC/cubit per feature (analytic, auth, product, etc.)
  common/
    api/                 # Base API client, endpoint helper
    constant/            # Application constants
    di/                  # Dependency injection setup (get_it, injectable)
    extension/           # Extensions
    function/            # General utility functions
    network/             # Connectivity checks, handlers
    painter/             # Custom painters
    theme/               # Colors, text styles, theming
    url/                 # Base URL/endpoints
    utils/               # Other helpers
    validator/           # Input validators
  domain/
    <feature>/           # Entities, repo interfaces, (use-cases if present)
  infrastructure/
    <feature>/           # Repo implementations, DTOs, API calls
  l10n/                  # ARB sources for i18n + generated localizations
  presentation/
    components/          # Reusable widgets
    pages/               # Feature pages/screens
    router/              # AutoRoute definitions
  env.dart               # Environment configuration (BASE_URL, etc.)
  injection.dart         # DI entry point
  injection.config.dart  # DI generated
  main.dart              # Application entry point
assets/
  images/, icons/, json/, fonts/
```

---

## Key Dependencies & Purpose

Runtime:

- `auto_route`: Automated, typed routing based on annotations.
- `flutter_bloc`: State management with BLoC/Cubit.
- `get_it`, `injectable`: Service locator + codegen for DI.
- `dio`, `awesome_dio_interceptor`: HTTP client + logging interceptor.
- `freezed_annotation`, `json_annotation`: Annotations for immutable data classes & JSON.
- `dartz`: Functional types (Either, Option) for explicit error handling.
- `connectivity_plus`, `device_info_plus`, `package_info_plus`: Device and connectivity info.
- `shared_preferences`: Local key-value storage.
- `image_picker`, `permission_handler`, `open_file`, `url_launcher`: OS/device integrations.
- UI: `flutter_svg`, `line_icons`, `flutter_spinkit`, `fl_chart`, `another_flushbar`, `table_calendar`, `shimmer`, `cached_network_image`, `syncfusion_flutter_datepicker`, `pdf`.

Dev:

- `build_runner`: Code generation orchestration.
- `auto_route_generator`, `injectable_generator`, `freezed`, `json_serializable`: Related generators.
- `flutter_gen_runner`: Typed asset access generator.
- `flutter_lints`: Recommended Flutter lints.
- `flutter_launcher_icons`: Launcher icon generation.

Refer to `pubspec.yaml` for full version constraints.

---

## Code Generation

**Full guide: [docs/codegen.md](docs/codegen.md)** — read it before your first codegen run.

Codegen runs on a pinned SDK (Flutter 3.41.9 / Dart 3.11.5 via FVM), not on the global Flutter 3.47:
`freezed 2.5.8` caps `analyzer` below 8.0.0, and analyzer 7.7.1 crashes on the dot-shorthand syntax
used by Dart 3.13 sources. The app itself still runs and builds with the global SDK.

Common commands:

```powershell
$FVM = "$env:USERPROFILE\fvm\versions\3.41.9\bin"

& "$FVM\flutter.bat" pub get
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs
# or watch
& "$FVM\dart.bat" run build_runner watch --delete-conflicting-outputs
flutter pub get   # restore lockfile resolution for the global SDK
```

> `--delete-conflicting-outputs` wipes every generated file first. If you cancel the build midway,
> restore them with `git checkout` — see the troubleshooting table in [docs/codegen.md](docs/codegen.md).

### Asset generation (flutter_gen_runner)

`flutter_gen_runner` is integrated with `build_runner`. Running the commands above will also generate typed accessors for assets based on the `flutter_gen` section in `pubspec.yaml`:

- Output path: `lib/presentation/components/assets/`
- SVG integration: enabled (`flutter_svg: true`)

Usage in code example (after generation):

```dart
// Example usage
// import 'presentation/components/assets/assets.gen.dart';
// Image.asset(Assets.images.logo.path);
```

Generators used:

- AutoRoute: Generates router and typed routes.
- Injectable: Generates DI registrations (`injection.config.dart`).
- Freezed: Generates immutable data classes, copyWith, unions, etc.
- Json Serializable: Generates toJson/fromJson for DTOs.
- FlutterGen: Generates static asset access under `lib/presentation/components/assets/`.

---

## Internationalization (i18n)

- Source files live in `lib/l10n/app_*.arb` (e.g., `app_en.arb`, `app_id.arb`).
- To add a language: create `app_<code>.arb`, then run code generation.
- Ensure `MaterialApp` is wired with `localizationsDelegates` and `supportedLocales` (already prepared).

---

## Theming & Assets

- Theme files live under `lib/common/theme/`.
- Fonts: `Quicksand` family is declared in `pubspec.yaml`.
- Assets: `assets/images/`, `assets/icons/`, `assets/json/` – referenced via FlutterGen outputs at `lib/presentation/components/assets/`.

---

## Environment Configuration (`env.dart`)

The `lib/env.dart` file stores configuration values such as base URLs and debug flags. Adjust per environment (development/production) using flavors, environment variables, or branching as preferred by the team.

---

## Development Practices

- Routing: Define routes in `presentation/router`, then run code generation.
- DI: Annotate services/repositories with `@injectable`/`@LazySingleton`, generate code, and call `configureDependencies()` early in app startup.
- BLoC: Keep UI logic in the `application` layer and use `BlocBuilder`/`BlocListener` in the `presentation` layer.
- DTO ↔ Entity: Mapping resides in the `infrastructure` layer to keep domain pure.
- Error handling: Prefer `Either`/`Option` (`dartz`) or well-structured BLoC states.
- Linting: Follow `analysis_options.yaml`.

---

## Useful Commands

```bash
# Install dependencies
flutter pub get

# Format & Analyze
flutter format .
flutter analyze

# Localization (safe on the global SDK)
flutter gen-l10n

# Run by device
flutter devices
flutter run -d <device-id>
```

Code generation uses the pinned FVM SDK — see [docs/codegen.md](docs/codegen.md):

```powershell
& "$env:USERPROFILE\fvm\versions\3.41.9\bin\dart.bat" run build_runner build --delete-conflicting-outputs
```

---

## Additional Notes

- Launcher icons configured via `launcher_icon.yaml`.
- Platform-specific configuration (Android/iOS/Web/Desktop) resides in respective platform folders.
- Review `analysis_options.yaml` for code style and lint rules.

---

## Launcher Icons

Configured via `launcher_icon.yaml` at the repository root. To (re)generate launcher icons, run:

```bash
dart run flutter_launcher_icons -f launcher_icon.yaml
```

If you prefer the Flutter shim:

```bash
flutter pub run flutter_launcher_icons -f launcher_icon.yaml
```

Ensure you have the package in `dev_dependencies` (`flutter_launcher_icons`).

## Contributing

1. Branch off `main`.
2. Make focused changes and provide a clear PR description.
3. Ensure build, lints, and codegen are clean before opening the PR.

---

## License

This project is private/internal. Contact the repository owner for usage permissions.

## Apskel Owner Flutter

Aplikasi Point of Sale (POS) untuk pemilik usaha, dibangun dengan Flutter. Proyek ini menerapkan arsitektur berlapis (presentation → application → domain → infrastructure) dengan dependency injection, state management, routing terotomasi, internationalization, dan code generation.

---

### Isi Dokumen

- Ringkasan Teknis
- Persyaratan & Setup
- Menjalankan Aplikasi
- Arsitektur & Alur
- Struktur Proyek
- Dependensi Utama & Fungsinya
- Code Generation (lihat docs/codegen.md)
- Internationalization (i18n)
- Theming & Assets
- Konfigurasi Lingkungan (`env.dart`)
- Praktik Pengembangan

---

## Ringkasan Teknis

- SDK: Flutter (Material) dengan Dart ^3.8.1
- Target platform: Android, iOS, Web, Desktop (Windows, macOS, Linux)
- State management: `flutter_bloc`
- Routing: `auto_route`
- Dependency Injection: `get_it` + `injectable`
- HTTP Client: `dio` (+ `awesome_dio_interceptor`)
- Data class & serialization: `freezed` + `json_serializable`
- Localization: `flutter_localizations`, `l10n/*.arb`
- Assets generation: `flutter_gen`

---

## Persyaratan & Setup

### Prasyarat

- Flutter SDK terpasang sesuai panduan resmi (`https://flutter.dev/docs/get-started/install`)
- Versi Dart sesuai constraint: ^3.8.1
- Khusus untuk code generation: FVM + Flutter 3.41.9 (`dart pub global activate fvm && fvm install 3.41.9`) — lihat [docs/codegen.md](docs/codegen.md)

### Instalasi

```bash
git clone <repo-url-anda>
cd apskel_owner_flutter
flutter pub get
```

### Generate kode (wajib setelah clone atau mengubah anotasi)

> **Jangan jalankan codegen dengan Flutter 3.47 / Dart 3.13** — semua builder crash dengan
> `Missing implementation of visitDotShorthandPropertyAccess`. Codegen harus memakai Flutter 3.41.9
> (Dart 3.11.5) via FVM. Setup, perintah, dan troubleshooting lengkap: **[docs/codegen.md](docs/codegen.md)**.

```powershell
$FVM = "$env:USERPROFILE\fvm\versions\3.41.9\bin"

& "$FVM\flutter.bat" pub get
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs
flutter pub get   # kembalikan resolusi lockfile ke SDK global
```

> Jalankan ulang perintah di atas setiap kali Anda mengubah file yang menggunakan anotasi `@RoutePage()`, `@injectable`, `@freezed`, atau `@JsonSerializable`.

---

## Menjalankan Aplikasi

```bash
flutter run
```

Menentukan platform/target tertentu:

```bash
flutter run -d chrome
flutter run -d ios
flutter run -d android
```

Build release contoh:

```bash
flutter build apk --release
flutter build ios --release
flutter build web --release
```

---

## Arsitektur & Alur

Proyek mengikuti layering yang jelas:

- Presentation (`lib/presentation`): UI, widget, halaman, router.
- Application (`lib/application`): BLoC/cubit, use-case orkestra ringan, validasi input UI.
- Domain (`lib/domain`): Entitas, value object, repository interface, use-case (jika ada).
- Infrastructure (`lib/infrastructure`): Implementasi repository, data source (API/DB), mapping DTO.
- Common (`lib/common`): Utilitas umum, konstanta, theme, API base, DI bootstrap, extension, dll.

Alur umum:

1. UI memicu event →
2. BLoC di layer Application memanggil use-case/repo (Domain) →
3. Implementasi repo (Infrastructure) melakukan HTTP via `dio` →
4. Response dipetakan menjadi entity/domain →
5. State di-update kembali ke UI.

---

## Struktur Proyek

```
lib/
  application/           # BLoC/cubit per fitur (analytic, auth, product, dst.)
  common/
    api/                 # Base API client, endpoint helper
    constant/            # Konstanta aplikasi
    di/                  # Setup dependency injection (get_it, injectable)
    extension/           # Extension util
    function/            # Fungsi util umum
    network/             # Cek konektivitas, handler
    painter/             # Custom painter
    theme/               # Warna, text styles, theming
    url/                 # Base URL/endpoint
    utils/               # Helper lain
    validator/           # Validator input
  domain/
    <feature>/           # Entity, repo interface, (use-case bila ada)
  infrastructure/
    <feature>/           # Repo implementation, DTO, pemanggilan API
  l10n/                  # Berkas ARB untuk i18n + generated localizations
  presentation/
    components/          # Widget reusable
    pages/               # Halaman/layar fitur
    router/              # Definisi AutoRoute
  env.dart               # Konfigurasi environment (BASE_URL, dsb)
  injection.dart         # Entry point DI
  injection.config.dart  # DI generated
  main.dart              # Entrypoint aplikasi
assets/
  images/, icons/, json/, fonts/
```

---

## Dependensi Utama & Fungsinya

Runtime:

- `auto_route`: Routing terotomasi berbasis anotasi.
- `flutter_bloc`: State management dengan BLoC/Cubit.
- `get_it`, `injectable`: Service locator + codegen untuk DI.
- `dio`, `awesome_dio_interceptor`: HTTP client + logging interceptor.
- `freezed_annotation`, `json_annotation`: Anotasi untuk data class immutable & JSON.
- `dartz`: Functional types (Either, Option) untuk error handling yang eksplisit.
- `connectivity_plus`, `device_info_plus`, `package_info_plus`: Info perangkat & konektivitas.
- `shared_preferences`: Penyimpanan key-value lokal.
- `image_picker`, `permission_handler`, `open_file`, `url_launcher`: Integrasi perangkat/OS.
- UI: `flutter_svg`, `line_icons`, `flutter_spinkit`, `fl_chart`, `another_flushbar`, `table_calendar`, `shimmer`, `cached_network_image`, `syncfusion_flutter_datepicker`, `pdf`.

Dev:

- `build_runner`: Orkestrasi code generation.
- `auto_route_generator`, `injectable_generator`, `freezed`, `json_serializable`: Generator terkait.
- `flutter_gen_runner`: Generator akses asset terketik.
- `flutter_lints`: Linter rekomendasi Flutter.
- `flutter_launcher_icons`: Generate icon launcher.

Catatan versi lengkap tersedia di `pubspec.yaml`.

---

## Code Generation

**Panduan lengkap: [docs/codegen.md](docs/codegen.md)** — baca dulu sebelum codegen pertama kali.

Codegen dijalankan dengan SDK terpisah (Flutter 3.41.9 / Dart 3.11.5 via FVM), bukan Flutter global 3.47:
`freezed 2.5.8` mengunci `analyzer` di bawah 8.0.0, dan analyzer 7.7.1 crash pada sintaks *dot-shorthand*
milik Dart 3.13. Aplikasinya sendiri tetap di-`run`/`build` dengan SDK global.

Perintah umum:

```powershell
$FVM = "$env:USERPROFILE\fvm\versions\3.41.9\bin"

& "$FVM\flutter.bat" pub get
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs
# atau untuk watch
& "$FVM\dart.bat" run build_runner watch --delete-conflicting-outputs
flutter pub get   # kembalikan resolusi lockfile ke SDK global
```

> `--delete-conflicting-outputs` menghapus semua file generated lebih dulu. Kalau build dibatalkan di
> tengah jalan, pulihkan dengan `git checkout` — lihat tabel troubleshooting di [docs/codegen.md](docs/codegen.md).

Generator yang digunakan:

- AutoRoute: menghasilkan deklarasi router & route.
- Injectable: menghasilkan registrasi DI (`injection.config.dart`).
- Freezed: menghasilkan data class immutable, copyWith, union, dsb.
- Json Serializable: menghasilkan toJson/fromJson untuk DTO.
- FlutterGen: menghasilkan akses asset statis di `lib/presentation/components/assets/`.

---

## Internationalization (i18n)

- Berkas sumber ada di `lib/l10n/app_*.arb` (contoh: `app_en.arb`, `app_id.arb`).
- Bahasa baru: tambahkan `app_<kode>.arb`, jalankan code generation.
- Pastikan `MaterialApp` menggunakan `localizationsDelegates` dan `supportedLocales` (sudah disiapkan).

---

## Theming & Assets

- Theme ada di `lib/common/theme/`.
- Font: keluarga `Quicksand` dideklarasikan di `pubspec.yaml`.
- Assets: `assets/images/`, `assets/icons/`, `assets/json/` – akses via FlutterGen yang dihasilkan ke `lib/presentation/components/assets/`.

---

## Konfigurasi Lingkungan (`env.dart`)

File `lib/env.dart` menyimpan nilai konfigurasi seperti base URL, flag debug, dll. Sesuaikan untuk development/production (bisa dengan flavor, env var, atau branch khusus sesuai kebutuhan tim).

---

## Praktik Pengembangan

- Routing: definisikan route di `presentation/router`, jalankan codegen.
- DI: daftarkan service/repository dengan anotasi `@injectable`/`@LazySingleton`, lalu generate, dan panggil `configureDependencies()` di awal aplikasi.
- BLoC: simpan logic UI di layer `application` dan gunakan `BlocBuilder`/`BlocListener` di layer `presentation`.
- DTO ↔ Entity: mapping berada di layer `infrastructure` untuk menjaga domain tetap bersih.
- Error handling: gunakan `Either`/`Option` (`dartz`) atau state terstruktur di BLoC.
- Lint: patuhi aturan `analysis_options.yaml`.

---

## Perintah Berguna

```bash
# Install dependencies
flutter pub get

# Format & Analyze
flutter format .
flutter analyze

# Localization (aman dengan SDK global)
flutter gen-l10n

# Run by device
flutter devices
flutter run -d <device-id>
```

Code generation memakai SDK FVM yang di-pin — lihat [docs/codegen.md](docs/codegen.md):

```powershell
& "$env:USERPROFILE\fvm\versions\3.41.9\bin\dart.bat" run build_runner build --delete-conflicting-outputs
```

---

## Catatan Tambahan

- Icon launcher dikonfigurasi di `launcher_icon.yaml` (gunakan `flutter pub run flutter_launcher_icons` bila diperlukan).
- Konfigurasi platform (Android/iOS/Web/Desktop) berada pada folder platform terkait.
- Pastikan meninjau `analysis_options.yaml` untuk standar code style dan lints.

---

## Kontribusi

1. Buat branch dari `main`.
2. Lakukan perubahan terfokus dan sertakan deskripsi yang jelas pada PR.
3. Pastikan build, lints, dan codegen bersih sebelum mengajukan PR.

---

## Lisensi

Proyek ini bersifat privat/internal. Hubungi pemilik repositori untuk detail izin penggunaan.
