critical priority low complexity infrastructure pending devops specialist Tier 1

Acceptance Criteria

Three environment configurations exist: development (.env.dev), staging (.env.staging), and production (.env.prod) — each with SUPABASE_URL and SUPABASE_ANON_KEY
Running flutter run --dart-define-from-file=.env.dev boots with development credentials; same pattern works for staging and production
If SUPABASE_URL or SUPABASE_ANON_KEY is absent or empty at startup, the app throws an EnvironmentConfigException before Supabase.initialize() is called, with a message naming the missing key
All .env.* files are listed in .gitignore; only .env.example is committed to version control
CI/CD pipeline injects credentials via dart-define secrets (not checked-in files) — documented in README
Environment name is accessible at runtime via a typed EnvironmentConfig.current getter for debug overlays

Technical Requirements

frameworks
Flutter
flutter_dotenv (or dart-define-from-file)
apis
Supabase GoTrue Auth API
performance requirements
Credential loading adds less than 50ms to app startup time
security requirements
Production credentials must only be injected at build time via CI/CD secrets — never stored in the repository
flutter_dotenv .env files must be excluded from git and from the app bundle in release builds
dart-define values are compiled into the binary — treat them as semi-public; do not use for server-side secrets

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Prefer --dart-define-from-file over flutter_dotenv for production builds — it compiles values into the binary and avoids bundling .env files in the APK/IPA. Use flutter_dotenv only for local development convenience. Create an EnvironmentConfig class with static fields populated via String.fromEnvironment('SUPABASE_URL', defaultValue: '') and validate in main() before Supabase.initialize(). Document the three launch configurations in .vscode/launch.json and as Xcode schemes for iOS team members.

TestFlight builds (used for this project's beta testing) must use staging config, not production.

Testing Requirements

Unit tests: (1) EnvironmentConfig.validate() throws EnvironmentConfigException when SUPABASE_URL is empty; (2) throws when SUPABASE_ANON_KEY is missing; (3) returns valid config object when both keys are present. Use flutter_test with fake env maps injected via constructor to avoid file I/O in tests. Integration smoke test: boot the app against staging credentials and assert Supabase.instance.client is non-null.

Component
Supabase Auth Client
infrastructure low
Epic Risks (2)
high impact low prob integration

Supabase client initialization may fail silently in certain Flutter environments if environment variables are missing or the anon key is rotated, leading to runtime null-pointer errors throughout the auth layer.

Mitigation & Contingency

Mitigation: Add explicit assertion checks during app startup that verify the Supabase client is initialized before the router resolves. Document required --dart-define keys in the project README and add a CI step that validates their presence.

Contingency: Implement a fallback initialization error screen with a clear message and a retry button. Log initialization failures to crash reporting immediately.

medium impact medium prob technical

The flutter_secure_storage package behaviour differs between iOS Keychain and Android Keystore implementations. On Android, biometric-enrolled devices may require additional authentication to read stored tokens, causing unexpected session read failures.

Mitigation & Contingency

Mitigation: Test the repository on Android devices with and without biometric enrollment early in development. Use accessibility options in flutter_secure_storage to configure whether biometric authentication is required for storage access.

Contingency: If biometric-gated storage causes regressions, fall back to a non-biometric storage option for session tokens (reserving biometric-gated storage for higher-sensitivity credentials only).