# Configuration Architecture

## Overview

Configuration in this codebase is split across runtime application wiring, test-specific overrides, and environment-driven settings. The main goal is to keep behavior predictable while still allowing the application to adapt to deployment context, locale preferences, caching infrastructure, and integration-test setup.

The key idea is that configuration is not concentrated in a single module. Instead, Spring Boot assembles it from a small set of focused configuration classes and from externalized properties. This makes the application easier to run in different environments, and it gives tests a controlled way to exercise specific configuration paths.

## Implementation Patterns

### 1. Spring `@Configuration` classes define concern-specific wiring

The application uses small configuration classes that each own one cross-cutting concern:

- [`CacheConfiguration`](../src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java) enables Spring caching and creates the named JCache cache used by the application.
- [`WebConfiguration`](../src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java) configures locale handling and language switching.

This keeps infrastructure setup close to the feature it supports while still using standard Spring conventions.

### 2. Runtime behavior is driven by the Spring environment

The application relies on Spring's environment abstraction rather than hard-coding settings. The integration test in [`PostgresIntegrationTests`](../src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java) demonstrates this pattern clearly:

- the `postgres` profile is activated
- Docker Compose is configured through test properties
- a custom `PropertiesLogger` prints effective property values after the application context is prepared

This shows the codebase expects environment-specific behavior to be injected through properties and profiles, not through conditional logic scattered throughout the code.

### 3. Tests encode configuration expectations

Several tests validate configuration behavior as part of the build:

- [`I18nPropertiesSyncTest`](../src/test/java/org/springframework/samples/petclinic/system/I18nPropertiesSyncTest.java) ensures HTML and translation property files stay synchronized.
- [`CrashControllerIntegrationTests`](../src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java) overrides error and management settings to verify error handling behavior.
- [`PostgresIntegrationTests`](../src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java) asserts that a PostgreSQL-backed runtime can start with the right profile and Docker settings.

This makes configuration changes safer because the expected wiring is tested directly.

### 4. Locale and message files are treated as part of configuration

The i18n setup assumes a base `messages.properties` file plus locale-specific property files. `I18nPropertiesSyncTest` treats these files as configuration assets and checks that translations remain complete and aligned with the base keys.

That means user-facing text is managed as part of the configuration surface, not as loose static content.

### 5. Feature flags and operational switches come from properties

The codebase uses property-driven switches for behavior such as:

- including error details in the response payload during tests
- enabling or disabling actuator/management access in the test context
- choosing which profile-backed resources are active
- starting Docker Compose for Postgres-backed integration tests

These switches are surfaced through Spring Boot configuration rather than custom feature-flag infrastructure.

## Key Classes

### [`CacheConfiguration`](../src/main/java/org/springframework/samples/petclinic/system/CacheConfiguration.java)

This class enables caching and creates the `vets` cache. It uses JCache and turns on cache statistics, which allows cache behavior to be observed through standard monitoring channels.

Architecturally, it is the cache bootstrap point for the application. If caching behavior changes, this is the place where the application-level cache name and baseline cache capabilities are defined.

### [`WebConfiguration`](../src/main/java/org/springframework/samples/petclinic/system/WebConfiguration.java)

This class defines the application's locale strategy. It uses a session-based `LocaleResolver`, defaults users to English, and registers a `LocaleChangeInterceptor` that listens for the `lang` request parameter.

This is the main web-level configuration for internationalization. It makes language selection a request concern rather than a controller concern.

### [`PropertiesLogger`](../src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java)

This is a test-only helper that logs the resolved environment properties visible during application startup. It compares raw property values with resolved values and reports overrides.

It is important because it documents how the environment is composed at runtime and helps diagnose precedence issues between property sources.

### [`TestConfiguration`](../src/test/java/org/springframework/samples/petclinic/system/CrashControllerIntegrationTests.java)

This nested test application excludes data-source and JPA auto-configuration so the crash controller test can focus on error response behavior.

It is a useful example of test-scoped configuration that trims away unrelated infrastructure to make a narrow slice of behavior easier to validate.

### [`I18nPropertiesSyncTest`](../src/test/java/org/springframework/samples/petclinic/system/I18nPropertiesSyncTest.java)

This test enforces two configuration-quality rules:

- HTML content should not contain hard-coded user-facing strings where internationalization is expected
- locale-specific message property files must stay in sync with the base messages file

It acts as a guardrail for the application's message configuration and prevents translation drift.

## How It Fits Together

```mermaid
flowchart TD
A["Spring Boot Application"] --> B["Spring Environment"]
B --> C["CacheConfiguration"]
B --> D["WebConfiguration"]
B --> E["Test properties and profiles"]
C --> F["JCache cache vets"]
C --> G["Cache statistics"]
D --> H["SessionLocaleResolver"]
D --> I["LocaleChangeInterceptor"]
D --> J["lang request parameter"]
E --> K["CrashControllerIntegrationTests"]
E --> L["PostgresIntegrationTests"]
E --> M["PropertiesLogger"]
N["messages.properties and locale files"] --> D
N --> O["I18nPropertiesSyncTest"]
```

The application starts with Spring Boot building a shared environment from properties, profiles, and defaults. That environment feeds the runtime configuration classes:

- caching is bootstrapped through JCache
- locale handling is configured for session-based language selection
- tests layer on additional property values and profile choices to exercise targeted behavior
- translation files are validated so the user-facing configuration remains consistent

## Notes for Developers

- Prefer small, focused configuration classes over large monolithic setup code.
- Treat properties and profiles as part of the public behavior of the application; changes here can affect startup, tests, and runtime defaults.
- When adding new user-facing text, update the message property files and keep translation keys aligned across locales.
- If you add a new cache, follow the pattern in `CacheConfiguration`: define it centrally and enable the capabilities the application expects to observe.
- If you add a new test profile or environment override, document it in an integration test so the configuration remains executable and verifiable.
- Use `PropertiesLogger`-style inspection when diagnosing property precedence problems, especially in containerized or profile-driven runs.
- Keep web locale behavior in `WebConfiguration` rather than scattering language selection logic across controllers.
