> For the complete documentation index, see [llms.txt](https://docs.digit.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.digit.org/complaints-management/design/architecture/services/config-service.md).

# Config Service

## Overview

A schema-validated, tenant-scoped configuration store for the DIGIT platform. It manages template bindings, provider credentials, and notification channel toggles used by the WhatsApp notification system.

### Key Functionalities

* **Schema validation** against MDMS v2 schemas before storing data.
* **Tenant fallback resolution** via `_resolve` API (`pg.citya` -> `pg` -> `*`).
* **Field-level encryption** for sensitive fields (e.g., auth tokens) marked with `x-security` in schema.
* **Unique constraint enforcement** via `x-unique` schema fields.
* **Flyway-managed** database migrations.

## Pre-requisites

Before you proceed with the configuration, make sure the following prerequisites are met:

* Java 17
* PostgreSQL 14+
* MDMS v2 Service (running at `localhost:8083` or configured via `MDMS_V2_HOST`)

## Data Model

#### Physical Data Model

The service uses a single table `eg_config_data` to store various configuration types as JSONB, validated by their respective schemas.

<table><thead><tr><th width="165.640625">type</th><th width="209.2734375">column</th><th>Description</th></tr></thead><tbody><tr><td>string</td><td>id</td><td>Unique record ID (UUID)</td></tr><tr><td>string</td><td>tenantid</td><td>Tenant identifier</td></tr><tr><td>string</td><td>schemacode</td><td>Schema type (e.g., TemplateBinding)</td></tr><tr><td>string</td><td>uniqueidentifier</td><td>Derived from x-unique fields</td></tr><tr><td>jsonb</td><td>data</td><td>Configuration payload</td></tr><tr><td>boolean</td><td>isactive</td><td>Record status</td></tr><tr><td>string</td><td>createdby</td><td>Audit field</td></tr><tr><td>string</td><td>lastmodifiedby</td><td>Audit field</td></tr><tr><td>bigint</td><td>createdtime</td><td>Epoch timestamp</td></tr><tr><td>bigint</td><td>lastmodifiedtime</td><td>Epoch timestamp</td></tr></tbody></table>

### Schema Setup

Before creating any configuration data, the respective schemas must be registered in the **MDMS v2 service**. The `digit-config-service` uses these to validate data and enforce constraints.

#### 1. NotificationChannel Schema

Toggles notification channels (WHATSAPP, SMS, EMAIL) and links them to providers.

```
{
  "type": "object",
  "title": "NotificationChannel",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "code",
    "name",
    "enabled"
  ],
  "x-unique": [
    "code"
  ],
  "properties": {
    "code": {
      "type": "string",
      "enum": [
        "WHATSAPP",
        "SMS",
        "EMAIL"
      ],
      "description": "Channel identifier"
    },
    "name": {
      "type": "string",
      "description": "Human-readable channel name"
    },
    "enabled": {
      "type": "boolean",
      "description": "Whether this channel is active for the tenant"
    },
    "providerName": {
      "type": "string",
      "description": "Provider handling this channel (links to ProviderDetail)"
    },
    "priority": {
      "type": "integer",
      "description": "Dispatch priority (lower = higher priority)"
    }
  },
  "additionalProperties": true
}
```

#### 2. ProviderDetail Schema

Stores credentials for notification providers (e.g., Twilio).

```
{
  "type": "object",
  "title": "ProviderDetail",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "providerName",
    "channel",
    "priority"
  ],
  "x-unique": [
    "providerName",
    "channel",
    "priority"
  ],
  "properties": {
    "channel": {
      "type": "string",
      "description": "Communication channel (whatsapp, sms, email)"
    },
    "isActive": {
      "type": "boolean",
      "default": true,
      "description": "Whether this provider is active"
    },
    "priority": {
      "type": "integer",
      "default": 0,
      "description": "Provider priority (lower = higher priority)"
    },
    "novuApiKey": {
      "type": "string",
      "description": "Optional provider-specific Novu API key"
    },
    "credentials": {
      "type": "object",
      "description": "Provider-specific credentials in Novu-compatible format"
    },
    "providerName": {
      "type": "string",
      "description": "Provider name (e.g., twilio, sendgrid, etc.)"
    }
  },
  "x-security": [
    "credentials",
    "novuApiKey"
  ],
  "description": "Schema for provider configurations per tenant and channel"
}
```

#### 3. TemplateBinding Schema

Maps domain events to specific templates and locales.

```
{
  "type": "object",
  "title": "TemplateBinding",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventName",
    "channel",
    "templateId",
    "locale"
  ],
  "x-unique": [
    "eventName",
    "channel",
    "locale"
  ],
  "properties": {
    "locale": {
      "type": "string",
      "default": "en_IN",
      "pattern": "^[a-z]{2}_[A-Z]{2}$",
      "description": "Locale code for provider (e.g., en_IN, hi_IN, en_US)"
    },
    "channel": {
      "type": "string",
      "description": "Communication channel (whatsapp, sms, email)"
    },
    "isActive": {
      "type": "boolean",
      "default": true,
      "description": "Whether this template binding is active"
    },
    "eventName": {
      "type": "string",
      "description": "Event name (e.g., COMPLAINTS.WORKFLOW.REJECT)"
    },
    "contentSid": {
      "type": "string",
      "description": "Provider-specific content SID (for Twilio)"
    },
    "novuApiKey": {
      "type": "string",
      "description": "Optional template-specific Novu API key"
    },
    "paramOrder": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Order of parameters for template"
    },
    "templateId": {
      "type": "string",
      "description": "Template identifier in Novu"
    },
    "requiredVars": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Required variables for template"
    }
  },
  "x-security": [
    "novuApiKey"
  ],
  "description": "Schema for template bindings per event and channel"
}
```

### API Endpoints

**Base path:** `/config-service/config/v1`

<table><thead><tr><th width="232.05078125">Endpoint</th><th width="144.5">Method</th><th>Description</th></tr></thead><tbody><tr><td><code>/_create/{schemaCode}</code></td><td>POST</td><td>Create a new config record</td></tr><tr><td><code>/_update/{schemaCode}</code></td><td>POST</td><td>Update an existing config record</td></tr><tr><td><code>/_search</code></td><td>POST</td><td>Search records with exact tenant match</td></tr><tr><td><code>/_resolve</code></td><td>POST</td><td>Resolve config with tenant hierarchy fallback</td></tr></tbody></table>

#### Resolve Logic (Fallback Mechanism)

The `/_resolve` API implements a hierarchical lookup:

1. **Specific Tenant:** e.g., `pg.citya`
2. **Parent Tenant:** e.g., `pg` (if not found in citya)
3. **Wildcard:** `*` (if not found in parent)

## Setup

#### Build & Run

```
mvn clean package -DskipTests

java -jar target/digit-config-service-0.1.0-SNAPSHOT.jar \
  --spring.datasource.url=jdbc:postgresql://localhost:5432/configdb \
  --spring.datasource.username=postgres \
  --spring.datasource.password=password
```

#### Configuration Properties

| Property                      | Default                 | Description                           |
| ----------------------------- | ----------------------- | ------------------------------------- |
| `server.servlet.context-path` | `/config-service`       | API context path                      |
| `mdms.v2.host`                | `http://localhost:8083` | MDMS v2 service host                  |
| `encryption.service.enabled`  | `false`                 | Enable/Disable field-level encryption |
| `state.level.tenantid`        | `pg`                    | Tenant ID used for encryption keys    |

***

#### Helm Chart

**Location:** [`deploy-as-code/helm/charts/common-services/digit-config-service`](https://github.com/egovernments/Citizen-Complaint-Resolution-System/tree/master/devops/deploy-as-code/charts/common-services/digit-config-service)

*For full API details, refer to the* [*OpenAPI Spec*](https://github.com/egovernments/Citizen-Complaint-Resolution-System/blob/master/docs/Configs_Service/config-service.openapi.yaml)*.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.digit.org/complaints-management/design/architecture/services/config-service.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
