---
title: Configuration Settings Layer
---

# Specification: Configuration Settings Layer

## Objective

Centralise all runtime configuration (CLI arguments, environment variables, .env files, defaults) so that the rest of the application can rely on a single read-only settings object. This layer has no dependency on network or rendering code.

---

## 1. Sources & Precedence

1. **Command-line arguments** – highest priority.
2. **Environment variables** – fallback when corresponding CLI arg is `null`.
3. **.env file** – loaded from current working directory if present.
4. **Hard-coded defaults** – used when neither CLI, environment, nor .env provide a value.

Precedence is evaluated **per setting key**, not all-or-nothing.

---

## 2. Supported Settings Keys

| Key | Default | Env Var | CLI Flag | Notes |
|-----|---------|---------|----------|-------|
| `gitlab_host` | *(required)* | `GITLAB_HOST` | `--gitlab-host` | Base URL of GitLab instance. |
| `group_api_key` | *none* | `GROUP_API_KEY` | `--group-api-key` | Exactly one key or a JSON-List of keys. Stored as list of strings. |
| `debug` | `false` | `DEBUG` | `--debug` | Enables verbose logging. |
| `display_shared` | `false` | `DISPLAY_SHARED` | `--display-shared` | Includes shared projects in output when true. |
| `table_config` | `table_config.yaml` | `TABLE_CONFIG` | `--table-config` | Path to YAML file with column definitions (see [Table Rendering & UI](./spec_table_rendering_ui.md)). |
| `todo_keywords` | `["status", "todo", "stand", "fortschritt", "offen", "geplant"]` | `TODO_KEYWORDS` | `--todo-keywords` | JSON-List with strings of keywords. |
| `log_level` | `INFO` | `LOG_LEVEL` | `--log-level` | Root logger level. |
| `api_retry_count` | `3` | `API_RETRY_COUNT` | `--api-retry-count` | Max retries for API client. |
| `api_retry_backoff` | `1.0` | `API_RETRY_BACKOFF` | `--api-retry-backoff` | Seconds added per retry attempt (linear). |

---

## 3. Parsing Rules

* Boolean CLI Flags are either present (=`true`) or omitted (=`false`, the default).
* Boolean env vars accept `true/false`, `1/0`, `yes/no` (case-insensitive).
* Integer/float settings validate numeric input; invalid values raise configuration error at startup.
* File-path settings must point to readable files; resolved relative to the current working directory.
* **CLI value parsing**:
  * List fields accept JSON arrays or a single strings
  * Single values are automatically converted to single-item lists
  * Numeric fields are automatically converted from strings
  * Environment variables are temporarily unset when CLI values override them
* **Environment variable preprocessing**:
  * List fields (`group_api_key`, `todo_keywords`) accept JSON arrays or a single string
  * Single values are automatically converted to single-item lists
  * Invalid JSON (if not a single string) raises an error and aborts the program.
* **Validation behavior**:
  * File existence validation shows warnings instead of errors for missing files and prints the fallback-values in the INFO-Log
  * Numeric fields must be non-negative (`api_retry_count`, `api_retry_backoff`)
  * Invalid values raise configuration errors with descriptive messages and abort the program.

---

## 4. Runtime Behaviour

* Settings are evaluated once at process start and exposed as **immutable** object(s).
* Callers use helper class methods:
  * **current()** → load from environment only.
  * **from_args(parsed_args)** → merge CLI→env→defaults precedence.
  * **override(kwargs)** → return new Settings instance with overridden values.
* No part of the application may modify settings after creation.

---

## 5. Non-Goals

* Does not implement command-line parsing itself; relies on an external parser to create a namespace passed to `from_args`.
* Any dynamic reloading or hot-update of environment variables is out of scope.

---

## 6. Implementation Notes

* Uses Pydantic Settings for type safety and validation
* Ignores unknown fields (`extra="ignore"`)
* Provides automatic type conversion and validation
