Files
2026-08-14 16:42:12 +05:00

4.2 KiB

Configuration

All configuration lives in src/main/resources/application.properties. Values fall into two groups:

  • Non-secret defaults — model names, timeouts, retry policy, RSS URLs, log levels. These are literal values in the properties file and are safe to read in a review.
  • Secrets and environment-specific endpoints — resolved from environment variables via ${VAR} placeholders.

.env.example is the authoritative list of every variable, marked REQUIRED or OPTIONAL.

Secret handling

No credential is ever committed. Required secrets are declared without a fallback:

openai.api.key=${OPENAI_API_KEY}

If the variable is absent, Spring throws IllegalArgumentException: Could not resolve placeholder 'OPENAI_API_KEY' and the application refuses to start.

This is intentional. The alternative — an empty default — produces a service that boots happily and then fails every downstream call with an opaque 401, usually in production, usually at 3am. A startup failure names the missing variable immediately.

Optional values keep a default after the colon:

minio.bucket-name=${MINIO_BUCKET_NAME:konturai}

Adding a new configuration value

  1. If it is a credential, endpoint, or anything that differs per environment, use a ${VAR} placeholder — no default for required secrets.
  2. Add it to .env.example with a REQUIRED/OPTIONAL marker and a one-line comment.
  3. Add it to .env.production on the server before merging.

Never write a real value into application.properties, a test's @TestPropertySource, a shell script, or documentation.

The Google service-account key

NanoBananaImageGenerationService and GeminiVideoGenerationService authenticate to Vertex AI by loading keys/google-key.json from the classpath:

ClassPathResource resource = new ClassPathResource("keys/google-key.json");

The file must exist at src/main/resources/keys/google-key.json at build time, so it is baked into the jar. It is gitignored and must be supplied out of band:

cp /secure/path/google-key.json src/main/resources/keys/google-key.json

On the deployment host the file must be present in the checkout before the Docker image is built, since the Dockerfile uses COPY . ..

If the file is missing the application still starts — image and video generation log an error and return null, while every other feature keeps working.

Local development

cp .env.example .env
$EDITOR .env
set -a && source .env && set +a
./mvnw spring-boot:run

For a fully local setup you need MongoDB on localhost:27017. Point MINIO_ENDPOINT at a local MinIO container, or leave the storage-backed endpoints unused.

An alternative to .env is src/main/resources/application-local.properties (also gitignored), activated with --spring.profiles.active=local.

Configuration reference by area

Area Prefix Notes
MongoDB spring.data.mongodb.* 30s connect/socket/server-selection timeouts
Object storage minio.* Stores generated reports and images
Security security.jwt.*, encryption.* JWT secret must match the issuing auth service
OpenAI openai.* gpt-4o for text, gpt-4o-mini for cheaper calls; retry with exponential backoff, max 3 concurrent requests
Ollama ollama.* Self-hosted; very long timeouts (5h) for large generations
Vertex AI google.* Imagen 3 for images, Veo 3 for video; 20s rate-limit spacing
Serper serper.* Google search results for research reports
Facebook facebook.* Posting, plus the hot-leads collector and call-centre sync
RSS rss.* Five sources — see rss-parsers.md
Schedulers parser.scheduler.enabled, posting.scheduler.enabled Parser scheduler is off by default
CORS cors.* Bound by CorsProperties, applied in WebCorsConfig

Rotating a credential

  1. Issue the new credential with the provider.
  2. Update .env.production on the deployment host.
  3. Restart the container (docker compose up -d — see deployment.md).
  4. Revoke the old credential.

Because secrets are never baked into the image, rotation requires no rebuild.