Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/JonathanHerSa/xolo-api-hub/llms.txt

Use this file to discover all available pages before exploring further.

Xolo API Hub is a premium open-source Flutter mobile API client, and contributions from the community are very welcome. Whether you want to fix a bug, improve documentation, or build a new feature, this guide walks you through everything you need — from cloning the repository to submitting a pull request that passes the quality gate. Found a bug first? Open an issue. Have a bigger idea? Start a discussion before writing code.

Prerequisites

Before you begin, make sure the following tools are installed and available on your PATH:
ToolMinimum versionNotes
Flutter SDK3.32.0Pinned in CI (qa.yml). Use FVM or the official installer to pin this version.
Dart SDK^3.10.4Bundled with Flutter 3.32.0; declared in pubspec.yaml.
GitAny recent versionRequired for forking and branching.
Android SDKAPI level 21+Required for running emulator tests; flutter_launcher_icons sets min_sdk_android: 21.

Local Setup

1

Fork and clone the repository

Fork the project on GitHub, then clone your fork locally:
git clone https://github.com/<your-username>/xolo-api-hub.git
cd xolo-api-hub
Add the upstream remote so you can pull future changes:
git remote add upstream https://github.com/JonathanHerSa/xolo-api-hub.git
2

Install Flutter dependencies

Fetch all pub packages declared in pubspec.yaml:
flutter pub get
This resolves Drift, Riverpod, go_router, Dio, and the rest of the dependency tree.
3

Run code generation

Xolo uses Drift for reactive SQLite persistence. Drift generates a database.g.dart file via build_runner. You must run this before the app or tests will compile:
dart run build_runner build --delete-conflicting-outputs
This writes the generated file to lib/data/local/database.g.dart. The --delete-conflicting-outputs flag avoids stale-cache errors during re-runs.
4

Verify static analysis

Xolo enforces strict analysis with zero issues tolerated. Confirm your setup is clean:
flutter analyze
You should see No issues found! before making any changes. If you see existing issues, check that your Flutter version matches the pinned 3.32.0.
5

Run the test suite

Confirm all 221+ unit and widget tests pass on a fresh checkout:
flutter test
All tests should pass with no failures before you start any changes.
Code generation (build_runner) must be re-run any time you modify lib/data/local/tables.dart or add a new Drift table. Forgetting this step will cause compilation errors in database.g.dart referencing columns or queries that do not exist yet.

Project Conventions

Consistency across the codebase makes reviews faster and keeps the quality gate green. Please follow these conventions for all new code.

Architecture

Xolo follows a clean layered architecture:
  • Core — router, themes, secure storage, HTTP client, logging utilities.
  • Domain — repository contracts (XoloRepository), domain entities, and mappers that are completely independent of Drift row types.
  • Data — Drift database, DriftXoloRepository implementations, import and sync services.
  • Presentation — screens, reusable widgets, and Riverpod providers.
All new presentation code must access persistence through xoloRepositoryProvider only. Direct access to Drift tables, queries, or the AppDatabase instance from a screen, widget, or provider is not permitted. The repository layer is the single source of truth for the presentation tier.

Domain Services

New domain services (anything under lib/domain/services/ or lib/core/services/) must be pure classes — they may not import package:flutter/... or any Drift type directly. This constraint ensures every domain service is 100% unit-testable without spinning up a Flutter widget tree or a real SQLite database.

State Management

Use Riverpod providers for all shared state. Avoid setState except for isolated, self-contained widget internals (e.g., an animation controller that does not affect external state). Providers that fetch or mutate repository data should return AsyncValue and use ref.watch / ref.read correctly according to Riverpod 3.x conventions.

Naming Conventions

SuffixWhat it applies to
*EntityDomain objects returned by the repository layer (e.g., RequestEntity, CollectionEntity)
*ProviderRiverpod providers (e.g., collectionsProvider, requestControllerProvider)
*ScreenFull-page route destinations (e.g., ComposerScreen, HistoryScreen)
*WidgetReusable sub-tree components (e.g., RunProgressList, AuthTabWidget)

Internationalization

Xolo ships with full English and Spanish translations. Every user-visible string must be added to both locale files before a PR will be accepted.

ARB Files

Locale strings live in:
  • lib/l10n/app_en.arb — English (template locale, as declared in l10n.yaml)
  • lib/l10n/app_es.arb — Spanish
Add your key to both files:
// lib/l10n/app_en.arb
{
  "myNewKey": "My new label",
  "@myNewKey": {}
}
// lib/l10n/app_es.arb
{
  "myNewKey": "Mi nueva etiqueta"
}

l10n Configuration

The localization pipeline is configured in l10n.yaml:
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
Flutter’s gen-l10n tool reads these settings and writes the generated AppLocalizations class to lib/l10n/app_localizations.dart. The generated files are committed to the repository.

Using Strings in Widgets

Access localized strings via AppLocalizations.of(context)!:
import 'package:xolo/l10n/app_localizations.dart';

Text(AppLocalizations.of(context)!.myNewKey)
Supported locales are en and es, as declared in AppLocalizations.supportedLocales.

Adding a New Screen

1

Create the screen file

Add a new Dart file under lib/presentation/screens/. Follow the *Screen naming convention:
// lib/presentation/screens/my_feature_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class MyFeatureScreen extends ConsumerWidget {
  const MyFeatureScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // ...
  }
}
2

Register the route

Add the new route to lib/core/router/app_router.dart. Xolo uses go_router for navigation. Follow the existing route naming patterns — named routes use camelCase identifiers:
GoRoute(
  path: '/my-feature',
  name: 'myFeature',
  builder: (context, state) => const MyFeatureScreen(),
),
3

Add Riverpod providers

If your screen needs data or actions, create a dedicated provider file under lib/presentation/providers/. Provider files are named after the feature they support (e.g., my_feature_provider.dart). Keep providers focused — one provider file per feature domain keeps the codebase navigable.
4

Write tests

Every new screen or provider requires corresponding tests before the PR can merge:
  • Widget tests — place in test/presentation/ and use ProviderScope with mock overrides.
  • Integration tests — required for flows that involve navigation or multi-step user interactions.
The CI coverage gate requires 100% line coverage on all non-generated code. See the Quality Gate page for details.
Use AppLogger.warn() and AppLogger.error() instead of print() for any diagnostic output. The print statement is prohibited by linting rules and will cause flutter analyze to fail, blocking the CI pipeline on your PR.

Build docs developers (and LLMs) love