The Problem

Small restaurants need a low‑cost, offline‑first point‑of‑sale app that can track inventory, take orders, and produce printable receipts without relying on external services. Existing commercial solutions are expensive or require constant internet connectivity, creating a barrier for tight‑margin businesses.

What This Does

The repository implements a full Flutter application that runs on Android (and potentially iOS) devices.

  • lib/main.dart boots the app and injects the top‑level MyApp widget.
  • Navigation is defined in lib/routes.dart (≈ 729 lines) which maps URL‑style route names to widget factories.
  • UI components such as the menu, order entry, and analytics live under lib/ui/ and lib/components/.
  • Business logic for inventory, order persistence, and analytics resides in helper files like lib/helpers/logger.dart and lib/helpers/breakpoint.dart.
  • Platform‑specific code for Android is in android/app/src/main/kotlin/com/evanlu/possystem/MainActivity.kt; iOS stubs are under ios/.

The app stores data locally on the device (SQLite via the sqflite package, inferred from pubspec.yaml dependencies) and can export CSV/Excel files through the “Transit” feature (lib/ui/transit/plain_text/export_basic_view.dart).

How It Is Wired

  1. Startup – Execution begins at lib/main.dartrunApp(MyApp()).
  2. Dependency injectionMyApp creates a MaterialApp whose initialRoute is defined in lib/routes.dart.
  3. Routingroutes.dart holds a map of route strings to widget builders; each builder pulls required helpers (e.g., inventory service) from a singleton AppProvider defined elsewhere in lib/.
  4. Feature modules Inventory – UI in lib/ui/menu/ calls InventoryService (in lib/helpers/) which writes to the local DB. Order flowlib/ui/order/ widgets interact with OrderService; receipt printing uses PrinterHelper (found under lib/helpers/printer.dart). * Analyticslib/ui/analysis/ builds charts from data supplied by AnalyticsRepository.
  5. Platform bridges – Android channel communication is set up in android/app/src/main/kotlin/com/evanlu/possystem/MainActivity.kt, exposing Bluetooth printer APIs to Dart via MethodChannel.

Only two internal modules appear in the import graph, with no circular dependencies, so most changes stay local to a single feature folder. The largest blast‑radius files are lib/routes.dart (central navigation) and the oversized test mocks in test/mocks/.

How To Use It

# Clone the repository
git clone https://github.com/moses-y/flutter-pos-system.git
cd flutter-pos-system

# Install Flutter dependencies
flutter pub get

# Run the app on an attached device or emulator
flutter run

No additional environment variables are required; the app reads no external secrets at runtime. For Android builds, Gradle wrappers are configured in android/build.gradle and android/app/build.gradle. iOS build instructions are not present (iOS is “coming soon”).

Real‑World Use

A coffee shop installs the app on a cheap Android tablet. Staff open the menu screen (lib/ui/menu/), add items to an order, and tap “Print receipt”. The receipt is sent over Bluetooth via the PrinterHelper to a thermal printer. End‑of‑day, the manager opens the analytics screen (lib/ui/analysis/) to view sales trends without any internet connection.

Code Health & Issues

Measured findings (static analysis)

  • HIGH – Deep nesting – 20 files (e.g., lib/ui/transit/formatter/plain_text_formatter.dart) have indentation depth ≥ 10.
  • HIGH – Duplicated code blocks – 431 six‑line repeats across 85 files (e.g., lib/components/style/card_info_text.dart).
  • MEDIUM – File opened without context managerscripts/paint_introduce.py.
  • MEDIUM – Oversized fileslib/routes.dart, test/mocks/mock_google_api.mocks.dart, test/services/auth_test.mocks.dart each > 700 lines.
  • MEDIUM – High branching density – 21 files (e.g., lib/helpers/logger.dart) show > 50 branch points per ~150 lines.

Code‑health audit

  • CRITICAL – Secrets in workflow.github/workflows/deploy-to-playstore.yaml contains GH_READ_PAT, GOOGLE_SERVICES_JSON*, PLAY_STORE_UPLOAD_KEY.
  • HIGH – Unpinned GitHub Actions – All workflow files reference actions by tag (e.g., subosito/flutter-action@v2).
  • HIGH – Missing Gem lockfileandroid/Gemfile has no accompanying Gemfile.lock.
  • HIGH – CI never runs tests – No test step in any workflow despite 95 test files.
  • MEDIUM – Least‑privilege GITHUB_TOKEN – Workflow lacks explicit permissions block.
  • MEDIUM – No Dependabot – No dependabot.yml to keep dependencies current.
  • MEDIUM – No dependency‑vulnerability scan – No dependency-review-action or similar step.
  • MEDIUM – Large binaries in repodocs/images/ham-burger.jpg (14 MB) and Tra-Chi.ttf (8 MB) exceed 5 MB.
  • LOW – No job timeouts – Workflows omit timeout-minutes.
  • LOW – Missing convention files – No .editorconfig, .gitattributes, or formatter config.

The Bottom Line

The project delivers a functional offline POS app with a clear Flutter codebase, but the code quality suffers from deep nesting, duplicated blocks, and several oversized files. CI security is a serious concern: secrets are exposed in workflows and tests are never executed. For a small restaurant willing to invest in code cleanup and CI hardening, the app provides a solid starting point; teams lacking security expertise should address the critical workflow issues before production use.