MATIH Platform is in active MVP development. Documentation reflects current implementation status.
8. Platform Services
Configuration Management

Configuration Management

Configuration management is the core capability of the Config Service. The ConfigController at /api/v1/configs provides full CRUD operations for configuration entries with automatic versioning, hierarchical resolution, rollback to any previous version, and category-based organization.


ConfigController Overview

The controller is implemented in ConfigController.java and uses ConfigService and ConfigVersionService for business logic:

@RestController
@RequestMapping("/api/v1/configs")
@Tag(name = "Configuration", description = "Configuration management endpoints")
public class ConfigController {
    private final ConfigService configService;
    private final ConfigVersionService versionService;
    private final ConfigMapper configMapper;
}

Create a Configuration Entry

Create a new configuration entry with tenant scoping, category, and value type.

Endpoint: POST /api/v1/configs

Request:

curl -X POST http://localhost:8888/api/v1/configs \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "X-User-Id: 550e8400-e29b-41d4-a716-446655440001" \
  -d '{
    "tenantId": "550e8400-e29b-41d4-a716-446655440000",
    "configKey": "query.timeout",
    "configValue": "60s",
    "category": "query-engine",
    "description": "Maximum query execution timeout",
    "environment": "production",
    "valueType": "STRING",
    "encrypted": false
  }'

Response (201 Created):

{
  "id": "770e8400-e29b-41d4-a716-446655440000",
  "tenantId": "550e8400-e29b-41d4-a716-446655440000",
  "configKey": "query.timeout",
  "configValue": "60s",
  "category": "query-engine",
  "description": "Maximum query execution timeout",
  "environment": "production",
  "valueType": "STRING",
  "encrypted": false,
  "version": 1,
  "createdAt": "2026-02-12T10:00:00Z",
  "updatedAt": "2026-02-12T10:00:00Z"
}

Get Configuration by ID

Retrieve a specific configuration entry by its UUID.

Endpoint: GET /api/v1/configs/{id}

curl http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer ${TOKEN}"

Get Configuration by Tenant and Key

Look up a configuration by the combination of tenant ID and configuration key.

Endpoint: GET /api/v1/configs/tenant/{tenantId}/key/{configKey}

curl http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/key/query.timeout \
  -H "Authorization: Bearer ${TOKEN}"

Hierarchical Resolution

Resolve a configuration key using the four-level hierarchy (global, environment, tenant, tenant+environment). This is the recommended endpoint for services that need the effective configuration value.

Endpoint: GET /api/v1/configs/tenant/{tenantId}/key/{configKey}/resolve

curl "http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/key/query.timeout/resolve?environment=production" \
  -H "Authorization: Bearer ${TOKEN}"

The resolution order:

  1. Tenant + environment specific entry
  2. Tenant-level entry (any environment)
  3. Global entry (null tenantId)

Get Configuration Value Only

Returns just the value string, useful for lightweight lookups where the full metadata is not needed.

Endpoint: GET /api/v1/configs/tenant/{tenantId}/value/{configKey}

curl "http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/value/query.timeout?environment=production" \
  -H "Authorization: Bearer ${TOKEN}"

Response:

{
  "value": "120s"
}

List Tenant Configurations

Retrieve all configurations for a tenant with pagination.

Endpoint: GET /api/v1/configs/tenant/{tenantId}

curl "http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000?page=0&size=20&sort=configKey,asc" \
  -H "Authorization: Bearer ${TOKEN}"

Response:

{
  "content": [
    {
      "id": "770e8400-...",
      "configKey": "ai.model",
      "configValue": "gpt-4",
      "category": "ai-service",
      "version": 3
    },
    {
      "id": "880e8400-...",
      "configKey": "query.max-rows",
      "configValue": "10000",
      "category": "query-engine",
      "version": 1
    }
  ],
  "totalElements": 42,
  "totalPages": 3,
  "size": 20,
  "number": 0
}

Get Configurations by Category

Group configurations by their category (e.g., query-engine, ai-service, bi-service).

Endpoint: GET /api/v1/configs/tenant/{tenantId}/category/{category}

curl http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/category/query-engine \
  -H "Authorization: Bearer ${TOKEN}"

Search Configurations

Search configurations by key pattern using SQL LIKE matching.

Endpoint: GET /api/v1/configs/tenant/{tenantId}/search

curl "http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/search?pattern=query.%" \
  -H "Authorization: Bearer ${TOKEN}"

Global Configurations

Retrieve platform-wide default configurations (entries where tenantId is null).

Endpoint: GET /api/v1/configs/global

curl http://localhost:8888/api/v1/configs/global \
  -H "Authorization: Bearer ${TOKEN}"

Update a Configuration Entry

Update an existing configuration. This automatically creates a new version in the version history.

Endpoint: PUT /api/v1/configs/{id}

curl -X PUT http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "X-User-Id: 550e8400-e29b-41d4-a716-446655440001" \
  -d '{
    "configValue": "120s",
    "description": "Increased timeout for enterprise workloads"
  }'

Every update creates a new version entry in the config_versions table, preserving the complete change history.


Delete a Configuration Entry

Soft-delete a configuration entry with an optional reason for the audit trail.

Endpoint: DELETE /api/v1/configs/{id}

curl -X DELETE "http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000?reason=Deprecated%20setting" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "X-User-Id: 550e8400-e29b-41d4-a716-446655440001"

Response: 204 No Content


Version History

Every configuration entry maintains a full version history. Each update increments the version number and stores the previous value.

Get Version History

Endpoint: GET /api/v1/configs/{id}/versions

curl "http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000/versions?page=0&size=20" \
  -H "Authorization: Bearer ${TOKEN}"

Response:

{
  "content": [
    {
      "id": "ver-003",
      "configEntryId": "770e8400-...",
      "versionNumber": 3,
      "configValue": "120s",
      "changedBy": "550e8400-...001",
      "changeReason": "Increased for enterprise workloads",
      "createdAt": "2026-02-12T14:00:00Z"
    },
    {
      "id": "ver-002",
      "configEntryId": "770e8400-...",
      "versionNumber": 2,
      "configValue": "90s",
      "changedBy": "550e8400-...001",
      "changeReason": "Performance tuning",
      "createdAt": "2026-02-10T09:00:00Z"
    },
    {
      "id": "ver-001",
      "configEntryId": "770e8400-...",
      "versionNumber": 1,
      "configValue": "60s",
      "changedBy": "system",
      "changeReason": "Initial creation",
      "createdAt": "2026-01-15T08:00:00Z"
    }
  ],
  "totalElements": 3,
  "totalPages": 1
}

Get Specific Version

Endpoint: GET /api/v1/configs/{id}/versions/{versionNumber}

curl http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000/versions/1 \
  -H "Authorization: Bearer ${TOKEN}"

Rollback to Previous Version

Rollback a configuration entry to any previous version. The rollback itself creates a new version entry.

Endpoint: POST /api/v1/configs/{id}/rollback

curl -X POST http://localhost:8888/api/v1/configs/770e8400-e29b-41d4-a716-446655440000/rollback \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "X-User-Id: 550e8400-e29b-41d4-a716-446655440001" \
  -d '{
    "versionNumber": 1,
    "reason": "Reverting to original timeout due to downstream issues"
  }'

Response (200 OK):

{
  "id": "770e8400-...",
  "configKey": "query.timeout",
  "configValue": "60s",
  "version": 4,
  "updatedAt": "2026-02-12T16:00:00Z"
}
⚠️

The rollback creates version 4 with the value from version 1. The version history is never rewritten -- it always moves forward.


Bulk Import

Import multiple configuration entries for a tenant in a single request.

Endpoint: POST /api/v1/configs/tenant/{tenantId}/import

curl -X POST http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/import \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "X-User-Id: 550e8400-e29b-41d4-a716-446655440001" \
  -d '[
    {
      "configKey": "query.timeout",
      "configValue": "60s",
      "category": "query-engine"
    },
    {
      "configKey": "query.max-rows",
      "configValue": "10000",
      "category": "query-engine"
    },
    {
      "configKey": "ai.model",
      "configValue": "gpt-4",
      "category": "ai-service"
    }
  ]'

Export Configurations

Export all configurations for a tenant as a key-value map.

Endpoint: GET /api/v1/configs/tenant/{tenantId}/export

curl http://localhost:8888/api/v1/configs/tenant/550e8400-e29b-41d4-a716-446655440000/export \
  -H "Authorization: Bearer ${TOKEN}"

Response:

{
  "query.timeout": "60s",
  "query.max-rows": "10000",
  "ai.model": "gpt-4",
  "bi.default-chart-type": "bar"
}

Error Codes

HTTP StatusError CodeDescription
400VALIDATION_ERRORInvalid request body or parameters
404CONFIG_NOT_FOUNDConfiguration entry does not exist
409CONFIG_KEY_EXISTSDuplicate key for the same tenant
422INVALID_VALUE_TYPEValue does not match declared type
500INTERNAL_ERRORUnexpected server error