VOZI uses two complementary configuration layers. Runtime credentials — specifically the Supabase project URL and anon key — are loaded from aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/AlonsoSam/vozi-android/llms.txt
Use this file to discover all available pages before exploring further.
.env file at startup using the flutter_dotenv package. Compile-time constants such as the app name, tagline, and adult PIN are defined as static const values in lib/core/config/app_config.dart. Neither file contains secrets that belong in version control: .env is listed in .gitignore, and AppConfig contains only non-sensitive demo values.
Environment Variables
VOZI reads two variables from the.env file at the root of the project. flutter_dotenv loads the file during main() before any other initialization runs. If the file is missing or either variable is blank, the app starts in fully local mode with no Supabase connection.
The
.env file is declared as a Flutter asset in pubspec.yaml so that flutter_dotenv can access it at runtime. It is explicitly excluded from version control via .gitignore. Never commit a .env file containing real credentials to the repository.The full HTTPS URL of your Supabase project, e.g.
https://abcdefghij.supabase.co. Found in your Supabase dashboard under Project Settings → API → Project URL. When this value is empty, SupabaseConfig.isConfigured returns false and Supabase is never initialized.The
anon / public API key for your Supabase project. Found in Project Settings → API → Project API Keys. This key is safe to include in a client app because Row Level Security (RLS) policies restrict what it can read or write. The service_role key must never be placed in this file or anywhere in the app..env file looks like this:
.env.example template committed to the repository ships with both values intentionally blank:
cp .env.example .env and fill in your own values before running the app.
App Config Constants
lib/core/config/app_config.dart holds compile-time constants that control global app identity and the adult PIN gate. These values are not secret and do not vary between environments.
| Constant | Type | Value | Description |
|---|---|---|---|
appName | String | 'VOZI' | Display name used across the UI. |
tagline | String | 'Aplicación educativa de práctica de sonidos' | Subtitle shown on splash / onboarding screens. |
parentPin | String | '1234' | PIN required to enter the adult dashboard (/parent-gate route). Demo-only; not a secure credential. |
parentPinLength | int | 4 | Drives the PIN input widget’s digit count. Must match the length of parentPin. |
Supabase Config
lib/core/config/supabase_config.dart is the single access point for Supabase credentials within the app. It reads SUPABASE_URL and SUPABASE_ANON_KEY from dotenv at runtime and exposes them through static getters.
_read helper catches any exception thrown when dotenv has not been initialized (for example, during unit tests or when .env is absent) and returns an empty string instead of crashing. This means:
isConfigured == true— bothurlandanonKeyare non-empty strings;SupabaseClientProvider.initialize()inmain.dartproceeds with Supabase setup.isConfigured == false— at least one credential is missing or blank; Supabase is never initialized and the app runs entirely on localshared_preferencesstorage.
SupabaseClientProvider.initialize() is called inside a try/catch in main(), so even a network failure or misconfigured URL during initialization will not prevent the app from launching.
Asset Structure
VOZI bundles all media assets inside theassets/ directory. These assets are declared in pubspec.yaml and packaged into the APK at build time. The directory layout is:
pubspec.yaml under the flutter: section:
.env itself is listed as an asset. This is required by flutter_dotenv to locate and read the file at runtime via Flutter’s asset bundle. Without this entry, dotenv.load() would fail even if the file exists on disk.
Audio playback for word pronunciations and feedback cues is handled by the audioplayers package. TTS via flutter_tts serves as a fallback when an MP3 for a specific word is not present in assets/audio/words/. Rive animations in assets/rive/ are rendered by the rive package and triggered when a child completes a full phoneme session.