Centralize environment configuration with validation#228
Centralize environment configuration with validation#228garciadias wants to merge 3 commits intodevelopfrom
Conversation
…onfig - Create flip-ui/src/utils/config.ts: validates required VITE_AWS_BASE_URL, VITE_AWS_USER_POOL_ID and VITE_AWS_CLIENT_ID at startup; provides typed access to all optional variables with sensible defaults - Strip all hardcoded constant definitions from public/js/window.js (keep only the Apache 2.0 header) - Remove Window interface properties for the removed constants from env.d.ts - Update api.ts, auth.ts and ModelUpload.vue to read configuration through getConfig() instead of window.* or process.env.VITE_* directly - Fail fast in main.ts: display a clear error in the browser if required environment variables are missing before the Vue app mounts - Add 22 unit tests for config validation and default-value behaviour - Update test/setup.ts to provide placeholder env vars so all existing tests continue to pass without individual mocking - Document required and optional VITE_* variables in flip-ui/README.md and .env.development.example Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com> Signed-off-by: Claude <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
This PR centralizes flip-ui environment configuration into a single validated getConfig() module, migrating key consumers off scattered process.env/window usage and improving startup failure visibility and documentation.
Changes:
- Added
src/utils/config.tswith required/optional env validation + typedAppConfig - Migrated config consumers (
auth.ts,api.ts,ModelUpload.vue,main.ts) to usegetConfig() - Updated docs and examples (
flip-ui/README.md,.env.development.example) and added unit tests for config behavior
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| flip-ui/test/setup.ts | Seeds env values for tests so config validation doesn’t fail globally |
| flip-ui/src/utils/config.ts | New centralized config reader/validator returning typed AppConfig |
| flip-ui/src/utils/auth.ts | Switched Cognito/local-mode logic to read from getConfig() |
| flip-ui/src/utils/tests/config.spec.ts | New unit tests covering required/optional env parsing and errors |
| flip-ui/src/services/api.ts | Uses config-derived base URL for Axios client |
| flip-ui/src/partials/models/ModelUpload.vue | Uses config-derived blacklist list source |
| flip-ui/src/main.ts | Attempts to show configuration errors early and uses config for local mode |
| flip-ui/src/env.d.ts | Removes window.* runtime config globals typing |
| flip-ui/README.md | Documents required vs optional env vars and troubleshooting |
| flip-ui/public/js/window.js | Removes hardcoded runtime config values |
| .env.development.example | Adds required/optional env variable guidance and placeholders |
Comments suppressed due to low confidence (1)
flip-ui/public/js/window.js:13
window.jshas been emptied but not deleted. Since it is still referenced byflip-ui/index.html, keeping an empty file adds an unnecessary request; deleting it will require updatingindex.htmlto remove the script tag. Either remove both (preferred) or keep a small stub with a comment explaining why it remains.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
| const _config = getConfig(); | ||
|
|
||
| export const authConfig = { | ||
| Auth: { | ||
| Cognito: { | ||
| region: process.env.VITE_AWS_REGION || 'eu-west-2', | ||
| userPoolId: process.env.VITE_AWS_USER_POOL_ID, | ||
| userPoolClientId: process.env.VITE_AWS_CLIENT_ID, | ||
| clientSecret: process.env.VITE_AWS_CLIENT_SECRET, | ||
| region: _config.awsRegion, | ||
| userPoolId: _config.awsUserPoolId, | ||
| userPoolClientId: _config.awsClientId, | ||
| clientSecret: _config.awsClientSecret, |
There was a problem hiding this comment.
authConfig is built from _config = getConfig() at module load time. If required env vars are missing, this will throw during import (before main.ts can catch and render the configuration error), defeating the intended fail-fast UI. Consider exporting a factory (e.g., getAuthConfig()), or building authConfig in main.ts after getConfig() succeeds (or passing AppConfig into an auth-config builder).
| let appConfig; | ||
| try { | ||
| appConfig = getConfig(); | ||
| } catch (error) { |
There was a problem hiding this comment.
let appConfig; introduces an implicit any under strict TypeScript settings, which can fail typechecking/linting. Prefer typing it (e.g., let appConfig: AppConfig) or use a typed const appConfig = getConfig() inside the try block.
| // Provide required environment variables so config validation passes in every test file. | ||
| // These are test-only placeholder values; they do not represent real credentials. | ||
| if (!import.meta.env['VITE_AWS_BASE_URL']) { | ||
| import.meta.env['VITE_AWS_BASE_URL'] = 'http://localhost:8080/api' | ||
| } | ||
| if (!import.meta.env['VITE_AWS_USER_POOL_ID']) { | ||
| import.meta.env['VITE_AWS_USER_POOL_ID'] = 'eu-west-2_TestPool' | ||
| } | ||
| if (!import.meta.env['VITE_AWS_CLIENT_ID']) { | ||
| import.meta.env['VITE_AWS_CLIENT_ID'] = 'test-client-id' | ||
| } |
There was a problem hiding this comment.
Directly mutating import.meta.env[...] is brittle in Vite/Vitest (and may be typed as read-only). Prefer using vi.stubEnv() for these defaults (and potentially vi.unstubAllEnvs() in teardown) so env setup is consistent and easily overridden per test.
- Remove flip-ui/public/js/window.js (now empty after constants were extracted) and its <script> tag from index.html, eliminating an unnecessary HTTP request on every page load - Change authConfig constant in auth.ts to a lazy getAuthConfig() function so that required-env validation does not fire during ES module evaluation (before main.ts can render the config error UI) - Fix main.ts: type appConfig as AppConfig (no implicit any); replace innerHTML string interpolation with DOM createElement + textContent to avoid an injection sink; import getAuthConfig() instead of the removed authConfig constant - Fix test/setup.ts: replace direct import.meta.env[] mutation with vi.stubEnv() calls, the correct Vitest API for environment stubs All 34 test files continue to pass (96 tests). Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com> Signed-off-by: Claude <noreply@anthropic.com>
|
Happy to take a look at this when I do the S3+Cloudfront implementation -- plan file |
…ility - config.ts now reads window.__FLIP_CONFIG__ (runtime) before falling back to import.meta.env (build-time). Runtime values take precedence so a single build artifact can be promoted across environments by swapping only /config.js, without a rebuild. - Add memoization to getConfig(): result is cached after first call so repeated invocations (api.ts, auth.ts, ModelUpload.vue) do not re-validate on every use. - Export _resetConfigForTesting() to allow tests to clear the cache between cases. - Add public/config.js: a documented empty stub loaded by index.html. In dev mode it is empty so import.meta.env is used unchanged; in S3+CloudFront deployments the pipeline replaces it with a generated file that sets window.__FLIP_CONFIG__. - Add Window.__FLIP_CONFIG__ TypeScript declaration to env.d.ts. - Expand config.spec.ts with 8 new tests covering the runtime config path (precedence, fallback, partial override, validation) and memoization behaviour (33 tests total, all pass). - Add auth.spec.ts: 3 unit tests for getAuthConfig() verifying the AppConfig → Amplify Cognito mapping. All 35 test files pass (107 tests). Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com> Signed-off-by: Claude <noreply@anthropic.com>
Description
Refactors environment variable handling by introducing a centralized configuration module (
config.ts) that validates required variables at application startup and provides a single source of truth for all configuration values.Key Changes
config.tsmodule: Centralizes all environment variable reading and validation with fail-fast behavior for missing required variableswindow.jswhich contained hardcoded configuration valuesauth.ts,api.ts,ModelUpload.vue, andmain.tsto usegetConfig()instead ofprocess.envorwindowglobalsBenefits
AppConfiginterface provides TypeScript support throughout the application.env.developmentvi.stubEnv()Linked Issues
Fixes #
Checklist
Type of Change
Testing
Added comprehensive unit tests in
config.spec.tscovering:All tests pass locally. Configuration validation is tested in isolation and integration with existing test setup ensures no regressions.
https://claude.ai/code/session_01Fi3u1Mvm2NDBXmx5DMNdjj