refactor(cleanup): Phase 3 — config hygiene
refactor(cleanup): Phase 3 — config hygiene
Section titled “refactor(cleanup): Phase 3 — config hygiene”Branch: refactor/cleanup-phase-3-config → refactor/cleanup-phase-2-renames (stacked; retarget to main once Phases 1–2 merge)
Phase 3 of docs/refactoring/architecture-cleanup-plan.md. The default build does not change: it still uses the production API, the production Turnstile key and the same Sentry settings.
Changes
Section titled “Changes”| Step | Change |
|---|---|
| 18 | New lib/core/config/app_config.dart with useStaging = bool.fromEnvironment('USE_STAGING'). In api_url_const.dart, the URL globals become const, and USE_STAGING=true switches api_static, api_dynamic and turnstileSiteId to the porikkhamulok values. Those values were previously commented-out lines, which are now deleted. site_uri stays mutable because AppBootstrap and LocalizationBloc rewrite it. Adds test/core/constant/api_url_const_test.dart |
| 19 | The four SENTRY_* String.fromEnvironment constants move from main.dart to app_config.dart with the same defaults, except that SENTRY_ENVIRONMENT defaults to staging under USE_STAGING. Adds test/core/config/app_config_test.dart |
| docs | README.md gains a table of the build-time defines. Adds a chorki (staging) launch configuration in .vscode/launch.json and updates the staging note in docs/api/README.md. The cleanup plan now marks Phases 0–3 as done and records where the work differed from the plan. Stale doc references to renamed or deleted files are fixed |
Where this differs from the plan doc
Section titled “Where this differs from the plan doc”The plan said the app defaulted to staging and that this PR would flip it to production. In fact api_url_const.dart already used production; the staging hosts were only commented out. So nothing flips, and no team sign-off is needed. The plan’s String.fromEnvironment('USE_STAGING', defaultValue: false) would not compile, so this PR uses bool.fromEnvironment instead.
How to use staging
Section titled “How to use staging”fvm flutter run -d <device> --dart-define=USE_STAGING=trueIn VS Code, pick the chorki (staging) launch configuration.
Verification
Section titled “Verification”fvm flutter analyze: 0 errors and 259 warnings, the same asmain. Infos are unchanged apart from renames: the URL globals now tripconstant_identifier_namesinstead ofnon_constant_identifier_names.fvm flutter test: 879 passed, including the 3 new tests. The only failures are the two that already fail onmain(category_screen_test“Songs paints no category strip” andfeed_tabs_shell_test“a single-feed shell paints no strip at all”).- The new tests pass both as-is and with
--dart-define=USE_STAGING=true. - The iOS Simulator was checked with a debug build in both modes. Request logging is compiled out, so the check relies on the API cache, whose keys contain the full URL:
- Default build: the cold start restored the production cache (
[boot] restoreLocal: navItems=4 home=true canRender=true). No Flutter exceptions appeared. USE_STAGING=truebuild: the same install missed the production home cache (home=false canRender=false). It then loaded the staging feed, whose images come fromimage-chorki.gotipath.com, a host that never appears in production runs. That CDN returned 504s, which is a staging backend problem.
- Default build: the cold start restored the production cache (
- E2E: not run. Two problems unrelated to this PR blocked it:
--suite smokeexited with code 3. The saved QA session token (issued 2026-09-14) now returns 401, so it needs a fresh token viae2e/scripts/session_from_token.sh.--suite launch --no-sessionfailed before any test ran, because Patrol’s simulator build broke indebug_unpack_ios. Under Xcode 27 (27A266a),lipo <Flutter> -verify_arch arm64 x86_64fails with “requires exactly one input file”, although-verify_archpasses for each architecture on its own. Flutter 3.41.8 runs that two-architecture check whenever it builds both simulator architectures, which also breaksflutter build ios --simulator.flutter runbuilds a single architecture and is not affected.
🤖 Generated with Claude Code