Skip to content

βš™οΈ Configuration ​

Config lives in environment variables β€” never hardcoded, never committed. This is factor III of our architecture.

The backend enforces this with Zod-validated config factories: each domain owns its config schema, reads from process.env, validates at startup, and throws if anything is missing or malformed. No silent misconfigurations.

Pattern ​

Each service has a *.config.ts that exports a typed factory function:

ts
// src/mongodb/mongodb.config.ts
export const MongoDbConfigSchema = z.object({
  uri: z
    .string()
    .min(1, 'MONGODB_URI is required')
    .default('mongodb://localhost:27017/'),
});

export default (base: BaseConfig): { mongodb: MongoDbConfig } => {
  const rawConfig = {
    uri: process.env.MONGODB_URI || `mongodb://localhost/${base.serviceName}`,
  };
  return { mongodb: MongoDbConfigSchema.parse(rawConfig) }; // throws if invalid
};

BaseConfig (from src/app.config.ts) provides shared values like environment, isProduction, isTest, derived from NODE_ENV.

Secrets ​

Secrets are managed via 1Password and injected as env vars at runtime. See Local Environment for setup.

Never log config values. Never commit .env files.