Skip to content

Dev Home

Florian DITTGEN edited this page Jun 1, 2026 · 5 revisions

Developer Guide

Technical documentation for contributing to or customising the app. All developer docs are in English — the user-facing wiki is translated per language.

The repo, bundle id (de.tankstellen.fuelprices) and internal package name stay tankstellen — the project's technical identity. Sparkilo is the public brand on the stores and the home-screen tile. These docs use tankstellen when referring to code/repo and Sparkilo for the product.

Platform parity (since 2026-05-08): features default to both iOS and Android. Single-platform features must follow the loosely-coupled plugin pattern documented in ADR 0009. iOS code-signing setup lives in docs/guides/ios-codesigning.md. Android releases ship via daily-beta.yml; iOS TestFlight via ios-testflight.yml — both must stay green on every PR.

Why this app exists (one paragraph)

Tankstellen (publicly Sparkilo) targets the running cost of a car through three layers: cheaper fuel at the pump (Layer 1 — 17 country open-data APIs + Open Charge Map for EV, route search with "best stops", per-station + radius alerts, the fuel-cost calculator, 30-day predictions), less consumption per kilometre (Layer 2 — OBD-II + GPS-only trip recording, driving-style score, eco-coaching with throttle/RPM histograms and a wasteful-behaviour breakdown, the approach overlay), and full transparency over what was actually spent (Layer 3 — fill-up log with pump/receipt OCR, consumption stats, the Trips logbook, the Carbon dashboard for cost + CO₂). When in doubt, ask: "Which layer does this feature serve?" — if the answer is "none," it doesn't ship.

Start here

Index

Architecture

Code patterns

Quality

  • Testing & TDD — 70/20/10 pyramid, fakes over mocks, mandatory pre-fix test protocol
  • Error Reporting & TracingTraceRecorder, error classification, global handlers, consent-gated reports

Deep dives

  • OBD2 Implementation — transport abstraction, adapter registry, PID parsing, permissions, auto-record state machine
  • Fuzzy Logic Price Predictions — the "best time to fill" recommendation engine, learning phase, limitations
  • Localization (ARB) — 23 locales, key-parity test, gen-l10n, ARB fragment pattern in lib/l10n/_fragments/

Workflow

  • CI/CD Pipeline — GitHub Actions, artefacts, release tagging, daily 18:00 Paris open-testing release
  • GitHub Workflow — Git flow, conventional commits, squash-merge, PR rules
  • Creating Issues — Templates, labels, milestones, triage
  • Contributing — Fork, branch, submit, customise for personal use
  • Adding a Country — Step-by-step playbook for a new country API

Reference


Core facts for contributors

Language Dart 3.11
Framework Flutter 3.41 (stable channel)
Lint flutter_lints + custom rules (see analysis_options.yaml); plain flutter analyze must pass with zero warnings (CI fails on info-level too)
State Riverpod 3 with @riverpod / @Riverpod(keepAlive: true) code-gen
Models Freezed + json_serializable
Storage Hive (encrypted boxes, AES from FlutterSecureStorage)
HTTP Dio with RateLimitInterceptor
Background WorkManager
Testing flutter_test, mocktail, coverage via flutter test --coverage; gate currently 40 % (was 45 %, see CHANGELOG 5.0.0)
Policy Zero flutter analyze warnings before commit; tests required for every change; new i18n keys go in lib/l10n/_fragments/<feature>_<locale>.arb (NOT in the aggregated app_*.arb files); features must serve at least one of the three savings layers

Clone this wiki locally