Skip to content

Tech Story: Add ConfigModule startup validation #97

@GitAddRemote

Description

@GitAddRemote

Tech Story

As a platform engineer, I want the application to validate all required environment variables at startup and fail fast with a clear error so that misconfigured deployments are caught immediately rather than producing cryptic runtime failures.

Context

ConfigModule.forRoot() is called without a validation schema. If JWT_SECRET, DATABASE_PASSWORD, ALLOWED_ORIGIN, or other required vars are absent, the app boots silently and fails at the first usage — often in a way that's hard to trace back to a missing env var.

Acceptance Criteria

  • ConfigModule.forRoot() includes a Joi validationSchema covering all required and optional env vars
  • App refuses to start if any required variable is missing, logging which variable is absent
  • Optional variables have sensible defaults declared in the schema (not scattered across service files)
  • .env.example updated to document every variable in the schema
  • Schema covers at minimum: JWT_SECRET, JWT_REFRESH_SECRET, DATABASE_HOST, DATABASE_PORT, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME, REDIS_HOST, REDIS_PORT, PORT, ALLOWED_ORIGIN, NODE_ENV, USE_REDIS_CACHE, FRONTEND_URL

Technical Elaboration

  • Install joi
  • Add to ConfigModule.forRoot():
    validationSchema: Joi.object({
      NODE_ENV: Joi.string().valid('development', 'production', 'test').default('development'),
      PORT: Joi.number().default(3001),
      JWT_SECRET: Joi.string().min(32).required(),
      JWT_REFRESH_SECRET: Joi.string().min(32).required(),
      ALLOWED_ORIGIN: Joi.string().uri().required(),
      DATABASE_HOST: Joi.string().required(),
      // ...etc
    }),
    validationOptions: { abortEarly: false },
  • Remove scattered process.env.X || 'default' patterns in main.ts in favour of ConfigService.get() with typed defaults from the schema

Notes

  • Test env (.env.test) must also satisfy the schema or use ignoreEnvVars for test-specific overrides
  • JWT_SECRET minimum length of 32 chars enforced at the Joi level prevents weak secrets in dev

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendBackend services and logicconfigConfiguration and feature flagstech-storyTechnical implementation story

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions