Files
cbsnexora-backend/fineract-provider/src/main/resources/application.properties
T
niteshandClaude Sonnet 5 04ac233fbe fix: share collection GL lookup, tenant chart-of-accounts cleanup, and dormancy/date fixes
- Add balancesheet API, GL account transaction guard, and disabled-feature filter
- Recognize an approved Clerk Disbursement Request (COLLECTION direction) as a
  second valid source when resolving a Share Advance Collection voucher, not
  just a Cashier Transaction Entry deposit
- Fix a NullPointerException in ShareAccount.getShareAccountTransaction() when
  an existing charge transaction has no total-shares/purchase-price recorded
- Null out DormancyClock's "last live" date before an account is ever
  activated, instead of falling through to the client's own KYC re-verification
  date via Postgres's null-skipping GREATEST()
- Stop seeding "Cash at Tellers" for new tenants (0502); drop the unused
  Facility & Service Charges Income accounts (0548); group header-less GL
  accounts under real-world header accounts (0549); uppercase GL account
  names and rename Share Sundry to match the bank's own chart (0550)
- Fix 0527's savings-daily-interest changeset to skip objects 0517 already
  creates on a fresh tenant, instead of failing tenant startup
- Update the local Postgres dev password default to match this environment

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 15:22:07 +05:30

823 lines
69 KiB
Properties

#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
application.title=Apache Fineract
fineract.node-id=${FINERACT_NODE_ID:1}
fineract.security.basicauth.enabled=${FINERACT_SECURITY_BASICAUTH_ENABLED:true}
fineract.security.oauth2.enabled=${FINERACT_SECURITY_OAUTH_ENABLED:false}
fineract.security.2fa.enabled=${FINERACT_SECURITY_2FA_ENABLED:true}
fineract.security.hsts.enabled=${FINERACT_SECURITY_HSTS_ENABLED:false}
#CORS configuration
fineract.security.cors.enabled=${FINERACT_SECURITY_CORS_ENABLED:true}
fineract.security.cors.allowed-origin-patterns=${FINERACT_SECURITY_CORS_ALLOWED_ORIGIN_PATTERNS:*}
fineract.security.cors.allowed-methods=${FINERACT_SECURITY_CORS_ALLOWED_METHODS:*}
fineract.security.cors.allowed-headers=${FINERACT_SECURITY_CORS_ALLOWED_HEADERS:*}
fineract.security.cors.exposed-headers=${FINERACT_SECURITY_CORS_EXPOSED_HEADERS:*}
fineract.security.cors.allow-credentials=${FINERACT_SECURITY_CORS_ALLOW_CREDENTIALS:true}
# EXAMPLE: OAuth2 client configuration (frontend-client)
fineract.security.oauth2.client.registrations.frontend-client.client-id=${FINERACT_SECURITY_OAUTH2_CLIENTS_FRONTEND_ID:frontend-client}
fineract.security.oauth2.client.registrations.frontend-client.scopes=${FINERACT_SECURITY_OAUTH2_CLIENTS_FRONTEND_SCOPES:read,write}
fineract.security.oauth2.client.registrations.frontend-client.authorization-grant-types=${FINERACT_SECURITY_OAUTH2_CLIENTS_FRONTEND_GRANTS:authorization_code,refresh_token}
fineract.security.oauth2.client.registrations.frontend-client.redirect-uris=${FINERACT_SECURITY_OAUTH2_CLIENTS_FRONTEND_REDIRECT:http://localhost:3000/callback}
fineract.security.oauth2.client.registrations.frontend-client.require-authorization-consent=${FINERACT_SECURITY_OAUTH2_CLIENTS_FRONTEND_CONSENT:false}
fineract.tenant.host=${FINERACT_DEFAULT_TENANTDB_HOSTNAME:localhost}
fineract.tenant.port=${FINERACT_DEFAULT_TENANTDB_PORT:5432}
fineract.tenant.username=${FINERACT_DEFAULT_TENANTDB_UID:postgres}
fineract.tenant.password=${FINERACT_DEFAULT_TENANTDB_PWD:313863}
fineract.tenant.parameters=${FINERACT_DEFAULT_TENANTDB_CONN_PARAMS:}
fineract.tenant.timezone=${FINERACT_DEFAULT_TENANTDB_TIMEZONE:Asia/Kolkata}
fineract.tenant.identifier=${FINERACT_DEFAULT_TENANTDB_IDENTIFIER:default}
fineract.tenant.name=${FINERACT_DEFAULT_TENANTDB_NAME:fineract_default}
fineract.tenant.description=${FINERACT_DEFAULT_TENANTDB_DESCRIPTION:Default Demo Tenant}
fineract.tenant.master-password=${FINERACT_DEFAULT_TENANTDB_MASTER_PASSWORD:fineract}
fineract.tenant.encrytion=${FINERACT_DEFAULT_TENANTDB_ENCRYPTION:"AES/CBC/PKCS5Padding"}
fineract.tenant.read-only-host=${FINERACT_DEFAULT_TENANTDB_RO_HOSTNAME:}
fineract.tenant.read-only-port=${FINERACT_DEFAULT_TENANTDB_RO_PORT:}
fineract.tenant.read-only-username=${FINERACT_DEFAULT_TENANTDB_RO_UID:}
fineract.tenant.read-only-password=${FINERACT_DEFAULT_TENANTDB_RO_PWD:}
fineract.tenant.read-only-parameters=${FINERACT_DEFAULT_TENANTDB_RO_CONN_PARAMS:}
fineract.tenant.read-only-name=${FINERACT_DEFAULT_TENANTDB_RO_NAME:}
fineract.tenant.config.min-pool-size=${FINERACT_CONFIG_MIN_POOL_SIZE:-1}
fineract.tenant.config.max-pool-size=${FINERACT_CONFIG_MAX_POOL_SIZE:-1}
fineract.tenant.config.rounding-mode=${FINERACT_CONFIG_ROUNDING_MODE:6}
fineract.mode.read-enabled=${FINERACT_MODE_READ_ENABLED:true}
fineract.mode.write-enabled=${FINERACT_MODE_WRITE_ENABLED:true}
fineract.mode.batch-worker-enabled=${FINERACT_MODE_BATCH_WORKER_ENABLED:true}
fineract.mode.batch-manager-enabled=${FINERACT_MODE_BATCH_MANAGER_ENABLED:true}
fineract.query.in-clause-parameter-size-limit=${FINERACT_QUERY_PARAMETER_SIZE:1000}
fineract.api.body-item-size-limit.inline-loan-cob=${FINERACT_API_REQUEST_BODY_SIZE_LIMIT_INLINE_COB:1000}
fineract.correlation.enabled=${FINERACT_LOGGING_HTTP_CORRELATION_ID_ENABLED:false}
fineract.correlation.header-name=${FINERACT_LOGGING_HTTP_CORRELATION_ID_HEADER_NAME:X-Correlation-ID}
fineract.job.stuck-retry-threshold=${FINERACT_JOB_STUCK_RETRY_THRESHOLD:5}
fineract.ip-tracking.enabled=${FINERACT_CLIENT_IP_TRACKING_ENABLED:false}
fineract.job.loan-cob-enabled=${FINERACT_JOB_LOAN_COB_ENABLED:true}
# Aggregation job configuration
fineract.job.journal-entry-aggregation.exclude-recent-N-days=${FINERACT_JOB_JOURNAL_ENTRY_AGGREGATION_EXCLUDE_RECENT_N_DAYS:1}
fineract.job.journal-entry-aggregation.enabled=${FINERACT_JOB_JOURNAL_ENTRY_AGGREGATION_ENABLED:true}
#this property if enabled, will create aggregated entry for all data on first run, instead of one entry per submitted_on_date
fineract.job.journal-entry-aggregation.chunk-size=${FINERACT_JOB_JOURNAL_ENTRY_AGGREGATION_CHUNK_SIZE:2000}
fineract.partitioned-job.partitioned-job-properties[0].job-name=LOAN_COB
fineract.partitioned-job.partitioned-job-properties[0].chunk-size=${LOAN_COB_CHUNK_SIZE:100}
fineract.partitioned-job.partitioned-job-properties[0].partition-size=${LOAN_COB_PARTITION_SIZE:100}
fineract.partitioned-job.partitioned-job-properties[0].thread-pool-core-pool-size=${LOAN_COB_THREAD_POOL_CORE_POOL_SIZE:5}
fineract.partitioned-job.partitioned-job-properties[0].thread-pool-max-pool-size=${LOAN_COB_THREAD_POOL_MAX_POOL_SIZE:5}
fineract.partitioned-job.partitioned-job-properties[0].thread-pool-queue-capacity=${LOAN_COB_THREAD_POOL_QUEUE_CAPACITY:20}
fineract.partitioned-job.partitioned-job-properties[0].retry-limit=${LOAN_COB_RETRY_LIMIT:5}
fineract.partitioned-job.partitioned-job-properties[0].poll-interval=${LOAN_COB_POLL_INTERVAL:10000}
fineract.remote-job-message-handler.spring-events.enabled=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED:true}
fineract.remote-job-message-handler.jms.enabled=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_ENABLED:false}
fineract.remote-job-message-handler.jms.request-queue-name=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_QUEUE_NAME:JMS-request-queue}
fineract.remote-job-message-handler.jms.broker-url=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_BROKER_URL:tcp://127.0.0.1:61616}
fineract.remote-job-message-handler.jms.broker-username=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_BROKER_USERNAME:}
fineract.remote-job-message-handler.jms.broker-password=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_JMS_BROKER_PASSWORD:}
fineract.remote-job-message-handler.kafka.enabled=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_ENABLED:false}
fineract.remote-job-message-handler.kafka.topic.auto-create=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_TOPIC_AUTO_CREATE:true}
fineract.remote-job-message-handler.kafka.topic.name=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_TOPIC_NAME:job-topic}
fineract.remote-job-message-handler.kafka.topic.replicas=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_TOPIC_REPLICAS:1}
fineract.remote-job-message-handler.kafka.topic.partitions=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_TOPIC_PARTITIONS:10}
fineract.remote-job-message-handler.kafka.bootstrap-servers=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_BOOTSTRAP_SERVERS:localhost:9092}
fineract.remote-job-message-handler.kafka.consumer.group-id=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_CONSUMER_GROUPID:fineract-consumer-group-id}
#defines the key and value separator, e.g.: key=value
fineract.remote-job-message-handler.kafka.consumer.extra-properties-key-value-separator=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_CONSUMER_EXTRA_PROPERTIES_KEY_VALUE_SEPARATOR:=}
#defines the item separator, e.g.: key1=value1|key2=value2
fineract.remote-job-message-handler.kafka.consumer.extra-properties-separator=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_CONSUMER_EXTRA_PROPERTIES_SEPARATOR:|}
#holds list of key value pairs using the above defined separators: key1=value1|key2=value2|...|keyn=valuen
fineract.remote-job-message-handler.kafka.consumer.extra-properties=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_CONSUMER_EXTRA_PROPERTIES:}
fineract.remote-job-message-handler.kafka.producer.extra-properties-separator=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_PRODUCER_EXTRA_PROPERTIES_SEPARATOR:|}
fineract.remote-job-message-handler.kafka.producer.extra-properties-key-value-separator=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_PRODUCER_EXTRA_PROPERTIES_KEY_VALUE_SEPARATOR:=}
fineract.remote-job-message-handler.kafka.producer.extra-properties=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_PRODUCER_EXTRA_PROPERTIES:}
fineract.remote-job-message-handler.kafka.admin.extra-properties-separator=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_ADMIN_EXTRA_PROPERTIES_SEPARATOR:|}
fineract.remote-job-message-handler.kafka.admin.extra-properties-key-value-separator=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_ADMIN_EXTRA_PROPERTIES_KEY_VALUE_SEPARATOR:=}
fineract.remote-job-message-handler.kafka.admin.extra-properties=${FINERACT_REMOTE_JOB_MESSAGE_HANDLER_KAFKA_ADMIN_EXTRA_PROPERTIES:}
fineract.events.external.enabled=${FINERACT_EXTERNAL_EVENTS_ENABLED:false}
fineract.events.external.partition-size=${FINERACT_EXTERNAL_EVENTS_PARTITION_SIZE:5000}
fineract.events.external.thread-pool-core-pool-size=${FINERACT_EVENT_TASK_EXECUTOR_CORE_POOL_SIZE:2}
fineract.events.external.thread-pool-max-pool-size=${FINERACT_EVENT_TASK_EXECUTOR_MAX_POOL_SIZE:25}
fineract.events.external.thread-pool-queue-capacity=${FINERACT_EVENT_TASK_EXECUTOR_QUEUE_CAPACITY:500}
fineract.events.external.producer.jms.enabled=${FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_ENABLED:false}
fineract.events.external.producer.jms.async-send-enabled=${FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_ASYNC_SEND_ENABLED:false}
fineract.events.external.producer.jms.event-queue-name=${FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_QUEUE_NAME:}
fineract.events.external.producer.jms.event-topic-name=${FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_TOPIC_NAME:}
fineract.events.external.producer.jms.broker-url=${FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_BROKER_URL:tcp://127.0.0.1:61616}
fineract.events.external.producer.jms.broker-username=${FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_BROKER_USERNAME:}
fineract.events.external.producer.jms.broker-password=${FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_BROKER_PASSWORD:}
fineract.events.external.producer.jms.producer-count=${FINERACT_EXTERNAL_EVENTS_PRODUCER_JMS_PRODUCER_COUNT:1}
fineract.events.external.producer.jms.thread-pool-task-executor-core-pool-size=${FINERACT_EVENT_TASK_EXECUTOR_CORE_POOL_SIZE:10}
fineract.events.external.producer.jms.thread-pool-task-executor-max-pool-size=${FINERACT_EVENT_TASK_EXECUTOR_MAX_POOL_SIZE:100}
fineract.events.external.producer.kafka.enabled=${FINERACT_EXTERNAL_EVENTS_KAFKA_ENABLED:false}
fineract.events.external.producer.kafka.timeout-in-seconds=${FINERACT_EXTERNAL_EVENTS_KAFKA_TIMEOUT_IN_SECONDS:10}
fineract.events.external.producer.kafka.topic.auto-create=${FINERACT_EXTERNAL_EVENTS_KAFKA_TOPIC_AUTO_CREATE:true}
fineract.events.external.producer.kafka.topic.name=${FINERACT_EXTERNAL_EVENTS_KAFKA_TOPIC_NAME:external-events}
fineract.events.external.producer.kafka.topic.replicas=${FINERACT_EXTERNAL_EVENTS_KAFKA_TOPIC_REPLICAS:1}
fineract.events.external.producer.kafka.topic.partitions=${FINERACT_EXTERNAL_EVENTS_KAFKA_TOPIC_PARTITIONS:10}
fineract.events.external.producer.kafka.bootstrap-servers=${FINERACT_EXTERNAL_EVENTS_KAFKA_BOOTSTRAP_SERVERS:localhost:9092}
fineract.events.external.producer.kafka.producer.extra-properties-separator=${FINERACT_EXTERNAL_EVENTS_KAFKA_PRODUCER_EXTRA_PROPERTIES_SEPARATOR:|}
fineract.events.external.producer.kafka.producer.extra-properties-key-value-separator=${FINERACT_EXTERNAL_EVENTS_KAFKA_PRODUCER_EXTRA_PROPERTIES_KEY_VALUE_SEPARATOR:=}
fineract.events.external.producer.kafka.producer.extra-properties=${FINERACT_EXTERNAL_EVENTS_KAFKA_PRODUCER_EXTRA_PROPERTIES:linger.ms=10|batch.size=16384}
fineract.events.external.producer.kafka.admin.extra-properties-separator=${FINERACT_EXTERNAL_EVENTS_KAFKA_ADMIN_EXTRA_PROPERTIES_SEPARATOR:|}
fineract.events.external.producer.kafka.admin.extra-properties-key-value-separator=${FINERACT_EXTERNAL_EVENTS_KAFKA_ADMIN_EXTRA_PROPERTIES_KEY_VALUE_SEPARATOR:=}
fineract.events.external.producer.kafka.admin.extra-properties=${FINERACT_EXTERNAL_EVENTS_KAFKA_ADMIN_EXTRA_PROPERTIES:}
fineract.task-executor.default-task-executor-core-pool-size=${FINERACT_DEFAULT_TASK_EXECUTOR_CORE_POOL_SIZE:10}
fineract.task-executor.default-task-executor-max-pool-size=${FINERACT_DEFAULT_TASK_EXECUTOR_MAX_POOL_SIZE:100}
# This is intentionally restricted to a single thread due to an outstanding Liquibase thread-safety issue: https://github.com/liquibase/liquibase/pull/7227
fineract.task-executor.tenant-upgrade-task-executor-core-pool-size=1
# This is intentionally restricted to a single thread due to an outstanding Liquibase thread-safety issue https://github.com/liquibase/liquibase/pull/7227
fineract.task-executor.tenant-upgrade-task-executor-max-pool-size=1
fineract.task-executor.tenant-upgrade-task-executor-queue-capacity=${FINERACT_TENANT_UPGRADE_TASK_EXECUTOR_QUEUE_CAPACITY:100}
fineract.idempotency-key-header-name=${FINERACT_IDEMPOTENCY_KEY_HEADER_NAME:Idempotency-Key}
fineract.loan.transactionprocessor.creocore.enabled=${FINERACT_LOAN_TRANSACTIONPROCESSOR_CREOCORE_ENABLED:true}
fineract.loan.transactionprocessor.early-repayment.enabled=${FINERACT_LOAN_TRANSACTIONPROCESSOR_EARLY_REPAYMENT_ENABLED:true}
fineract.loan.transactionprocessor.mifos-standard.enabled=${FINERACT_LOAN_TRANSACTIONPROCESSOR_MIFOS_STANDARD_ENABLED:true}
fineract.loan.transactionprocessor.heavensfamily.enabled=${FINERACT_LOAN_TRANSACTIONPROCESSOR_HEAVENSFAMILY_ENABLED:true}
fineract.loan.transactionprocessor.interest-principal-penalties-fees.enabled=${FINERACT_LOAN_TRANSACTIONPROCESSOR_INTEREST_PRINCIPAL_PENALTIES_FEES_ENABLED:true}
fineract.loan.transactionprocessor.principal-interest-penalties-fees.enabled=${FINERACT_LOAN_TRANSACTIONPROCESSOR_PRINCIPAL_INTEREST_PENALTIES_FEES_ENABLED:true}
fineract.loan.transactionprocessor.rbi-india.enabled=${FINERACT_LOAN_TRANSACTIONPROCESSOR_RBI_INDIA_ENABLED:true}
fineract.loan.transactionprocessor.due-penalty-fee-interest-principal-in-advance-principal-penalty-fee-interest.enabled=${FINERACT_LOAN_TRANSACTIONPROCESSOR_DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_ENABLED:true}
fineract.loan.transactionprocessor.due-penalty-interest-principal-fee-in-advance-penalty-interest-principal-fee.enabled=${FINERACT_LOAN_TRANSACTIONPROCESSOR_DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_ENABLED:true}
fineract.loan.transactionprocessor.advanced-payment-strategy.enabled=${FINERACT_LOAN_TRANSACTIONPROCESSOR_ADVANCED_PAYMENT_STRATEGY_ENABLED:true}
fineract.loan.transactionprocessor.error-not-found-fail=${FINERACT_LOAN_TRANSACTIONPROCESSOR_ERROR_NOT_FOUND_FAIL:true}
# Comma separated list of loan statuses which will be recorded on change. There are two extra values: "NONE" and "ALL".
# "NONE" disables the feature and no entries will be created, "ALL" enables the feature for all loan statuses.
fineract.loan.status-change-history-statuses=${FINERACT_LOAN_STATUS_CHANGE_HISTORY_STATUSES:NONE}
fineract.content.regex-whitelist-enabled=${FINERACT_CONTENT_REGEX_WHITELIST_ENABLED:true}
fineract.content.regex-whitelist=${FINERACT_CONTENT_REGEX_WHITELIST:.*\\.pdf$,.*\\.doc,.*\\.docx,.*\\.xls,.*\\.xlsx,.*\\.jpg,.*\\.jpeg,.*\\.png,.*\\.zip$,.*\\.csv$}
fineract.content.mime-whitelist-enabled=${FINERACT_CONTENT_MIME_WHITELIST_ENABLED:true}
fineract.content.mime-whitelist=${FINERACT_CONTENT_MIME_WHITELIST:application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,image/jpeg,image/png,application/zip,application/x-zip-compressed,application/octet-stream,text/csv}
fineract.content.default-buffer-size=${FINERACT_CONTENT_DEFAULT_BUFFER_SIZE:8192}
fineract.content.filesystem.enabled=${FINERACT_CONTENT_FILESYSTEM_ENABLED:true}
fineract.content.filesystem.rootFolder=${FINERACT_CONTENT_FILESYSTEM_ROOT_FOLDER:${user.home}/.fineract}
fineract.content.s3.enabled=${FINERACT_CONTENT_S3_ENABLED:false}
fineract.content.s3.bucketName=${FINERACT_CONTENT_S3_BUCKET_NAME:}
fineract.content.s3.accessKey=${FINERACT_CONTENT_S3_ACCESS_KEY:}
fineract.content.s3.secretKey=${FINERACT_CONTENT_S3_SECRET_KEY:}
fineract.content.s3.region=${FINERACT_CONTENT_S3_REGION:}
fineract.content.s3.endpoint=${FINERACT_CONTENT_S3_ENDPOINT:}
fineract.content.s3.path-style-addressing-enabled=${FINERACT_CONTENT_S3_PATH_STYLE_ADDRESSING_ENABLED:false}
spring.servlet.multipart.max-file-size=${FINERACT_MULTIPART_FILE_SIZE:5MB}
spring.servlet.multipart.max-request-size=${FINERACT_MULTIPART_REQUEST_SIZE:10MB}
fineract.template.regex-whitelist-enabled=${FINERACT_TEMPLATE_REGEX_WHITELIST_ENABLED:true}
fineract.template.regex-whitelist=${FINERACT_TEMPLATE_REGEX_WHITELIST:}
fineract.report.export.s3.bucket=${FINERACT_REPORT_EXPORT_S3_BUCKET_NAME:}
fineract.report.export.s3.enabled=${FINERACT_REPORT_EXPORT_S3_ENABLED:false}
fineract.jpa.statementLoggingEnabled=${FINERACT_STATEMENT_LOGGING_ENABLED:false}
fineract.database.defaultMasterPassword=${FINERACT_DEFAULT_MASTER_PASSWORD:fineract}
fineract.notification.user-notification-system.enabled=${FINERACT_USER_NOTIFICATION_SYSTEM_ENABLED:true}
fineract.logging.json.enabled=${FINERACT_LOGGING_JSON_ENABLED:false}
fineract.sampling.enabled=${FINERACT_SAMPLING_ENABLED:false}
fineract.sampling.samplingRate=${FINERACT_SAMPLING_RATE:1000}
fineract.sampling.sampledClasses=${FINERACT_SAMPLED_CLASSES:}
fineract.sampling.resetPeriodSec=${FINERACT_SAMPLING_RESET_PERIOD_IN_SEC:60}
#Modules
fineract.module.self-service.enabled=${FINERACT_MODULE_SELF_SERVICE_ENABLED:false}
fineract.module.investor.enabled=${FINERACT_MODULE_INVESTOR_ENABLED:true}
fineract.module.loan-origination.enabled=${FINERACT_MODULE_LOAN_ORIGINATION_ENABLED:true}
fineract.insecure-http-client=${FINERACT_INSECURE_HTTP_CLIENT:true}
fineract.client-connect-timeout=${FINERACT_CLIENT_CONNECT_TIMEOUT:30}
fineract.client-read-timeout=${FINERACT_CLIENT_READ_TIMEOUT:30}
fineract.client-write-timeout=${FINERACT_CLIENT_WRITE_TIMEOUT:30}
# sql validation
# inject-blind
fineract.sql-validation.patterns[0].name=inject-blind
fineract.sql-validation.patterns[0].pattern=(?i).*[\\"'`]?\\s*[and|or]+\\s*[\\"'`]?([\\d\\w])+[\\"'`]?\\s*=\\s*[\\"'`]?(\\1)[\\"'`]?\\s*.*
# detect-entry-point
fineract.sql-validation.patterns[1].name=detect-entry-point
fineract.sql-validation.patterns[1].pattern=(?i)^[\\"'`]?[\\)\\s]+
# inject-timing
fineract.sql-validation.patterns[2].name=inject-timing
fineract.sql-validation.patterns[2].pattern=(?i).*[\\"'`]?\\s*[and|\\+|&|\\|]+.*\\s*[sleep|pg_sleep|benchmark]+\\s*(\\(\\s*\\d+\\s*[,]?\\s*.*\\s*\\))+.*
# detect-backend
fineract.sql-validation.patterns[3].name=detect-backend
fineract.sql-validation.patterns[3].pattern=(?i).*\\[\\s*\\"(\\w+\\(.*\\))=(\\1)\\"\\s*,\\s*\\"\\w+\\"\\s*\\].*
# detect-column
fineract.sql-validation.patterns[4].name=detect-column
fineract.sql-validation.patterns[4].pattern=(?i).*[\\"'`]?\\s*(order\\s*by|group\\s*by|union\\s*select)+\\s+([\\d+|null]?\\s*,*\\s*)+\\s*.*
# detect-out-of-bands
fineract.sql-validation.patterns[5].name=detect-out-of-bands
fineract.sql-validation.patterns[5].pattern=(?i).*(select)+\\s+(load_file)+.*
# inject-stacked-query
fineract.sql-validation.patterns[6].name=inject-stacked-query
fineract.sql-validation.patterns[6].pattern=(?i).*[;]+\\s*(create|drop|alter|truncate|comment|select|insert|update|delete|merge|upsert|call|exec)+.*(from|into|set|table|column|database)*.*
# inject-comment
fineract.sql-validation.patterns[7].name=inject-comment
fineract.sql-validation.patterns[7].pattern=(?i).*\\s+(--|/\\*|#|\\(\\{)++.*
# main
fineract.sql-validation.profiles[0].name=main
fineract.sql-validation.profiles[0].description=Main Query Validation Profile
fineract.sql-validation.profiles[0].patternRefs[0].name=inject-blind
fineract.sql-validation.profiles[0].patternRefs[0].order=0
fineract.sql-validation.profiles[0].patternRefs[1].name=detect-entry-point
fineract.sql-validation.profiles[0].patternRefs[1].order=1
fineract.sql-validation.profiles[0].patternRefs[2].name=inject-timing
fineract.sql-validation.profiles[0].patternRefs[2].order=2
fineract.sql-validation.profiles[0].patternRefs[3].name=detect-backend
fineract.sql-validation.profiles[0].patternRefs[3].order=3
fineract.sql-validation.profiles[0].patternRefs[4].name=detect-column
fineract.sql-validation.profiles[0].patternRefs[4].order=4
fineract.sql-validation.profiles[0].patternRefs[5].name=detect-out-of-bands
fineract.sql-validation.profiles[0].patternRefs[5].order=5
fineract.sql-validation.profiles[0].patternRefs[6].name=inject-stacked-query
fineract.sql-validation.profiles[0].patternRefs[6].order=6
fineract.sql-validation.profiles[0].patternRefs[7].name=inject-comment
fineract.sql-validation.profiles[0].patternRefs[7].order=7
fineract.sql-validation.profiles[0].enabled=true
# adhoc
fineract.sql-validation.profiles[1].name=adhoc
fineract.sql-validation.profiles[1].description=Adhoc Query Validation Profile
fineract.sql-validation.profiles[1].patternRefs[0].name=inject-blind
fineract.sql-validation.profiles[1].patternRefs[0].order=0
fineract.sql-validation.profiles[1].patternRefs[1].name=detect-entry-point
fineract.sql-validation.profiles[1].patternRefs[1].order=1
fineract.sql-validation.profiles[1].patternRefs[2].name=inject-timing
fineract.sql-validation.profiles[1].patternRefs[2].order=2
fineract.sql-validation.profiles[1].patternRefs[3].name=detect-backend
fineract.sql-validation.profiles[1].patternRefs[3].order=3
fineract.sql-validation.profiles[1].patternRefs[4].name=detect-column
fineract.sql-validation.profiles[1].patternRefs[4].order=4
fineract.sql-validation.profiles[1].patternRefs[5].name=detect-out-of-bands
fineract.sql-validation.profiles[1].patternRefs[5].order=5
fineract.sql-validation.profiles[1].patternRefs[6].name=inject-stacked-query
fineract.sql-validation.profiles[1].patternRefs[6].order=6
fineract.sql-validation.profiles[1].patternRefs[7].name=inject-comment
fineract.sql-validation.profiles[1].patternRefs[7].order=7
fineract.sql-validation.profiles[1].enabled=true
# dynamic
fineract.sql-validation.profiles[2].name=column
fineract.sql-validation.profiles[2].description=Column Validation Profile
fineract.sql-validation.profiles[2].patternRefs[0].name=inject-blind
fineract.sql-validation.profiles[2].patternRefs[0].order=0
fineract.sql-validation.profiles[2].patternRefs[1].name=detect-entry-point
fineract.sql-validation.profiles[2].patternRefs[1].order=1
fineract.sql-validation.profiles[2].patternRefs[2].name=inject-timing
fineract.sql-validation.profiles[2].patternRefs[2].order=2
fineract.sql-validation.profiles[2].patternRefs[3].name=detect-backend
fineract.sql-validation.profiles[2].patternRefs[3].order=3
fineract.sql-validation.profiles[2].patternRefs[4].name=detect-out-of-bands
fineract.sql-validation.profiles[2].patternRefs[4].order=4
fineract.sql-validation.profiles[2].patternRefs[5].name=inject-stacked-query
fineract.sql-validation.profiles[2].patternRefs[5].order=5
fineract.sql-validation.profiles[2].patternRefs[6].name=inject-comment
fineract.sql-validation.profiles[2].patternRefs[6].order=6
fineract.sql-validation.profiles[2].enabled=true
#Cache - Default
fineract.cache.default-template.ttl=1m
fineract.cache.default-template.maximum-entries=1000
#Cache - Customization
fineract.cache.custom-templates.userTFAccessToken.ttl=2h
fineract.cache.custom-templates.userTFAccessToken.maximum-entries=10000
# Logging pattern for the console
logging.pattern.console=${CONSOLE_LOG_PATTERN:%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%replace([%X{correlationId}]){'\\[\\]', ''}) [%15.15tenantId] %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}}
logging.pattern.level=%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]
management.health.jms.enabled=${FINERACT_MANAGEMENT_HEALTH_JMS_ENABLED:false}
# FINERACT 1296
management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true
management.health.ratelimiters.enabled=${FINERACT_MANAGEMENT_HEALTH_RATELIMITERS_ENABLED:false}
management.endpoints.web.cors.allowed-origins=*
management.endpoints.web.cors.allowed-methods=GET, POST, PUT, DELETE, OPTIONS
management.endpoints.web.cors.allowed-headers=*
# FINERACT-883
management.info.git.mode=FULL
management.endpoints.web.exposure.include=${FINERACT_MANAGEMENT_ENDPOINT_WEB_EXPOSURE_INCLUDE:health,info,prometheus}
management.tracing.enabled=${FINERACT_MANAGEMENT_TRACIING_ENABLED:false}
management.metrics.tags.application=${FINERACT_MANAGEMENT_METRICS_TAGS_APPLICATION:fineract}
management.metrics.distribution.percentiles-histogram.http.server.requests=${FINERACT_MANAGEMENT_METRICS_DISTRIBUTION_HTTP_SERVER_REQUESTS:false}
management.otlp.metrics.export.enabled=${FINERACT_MANAGEMENT_OLTP_ENABLED:false}
management.otlp.metrics.export.url=${FINERACT_MANAGEMENT_OLTP_METRICS_EXPORT_URL:http://tempo:4318/v1/traces}
management.otlp.metrics.export.aggregationTemporality=${FINERACT_MANAGEMENT_OLTP_METRICS_EXPORT_AGGREGATION_TEMPORALITY:cumulative}
management.prometheus.metrics.export.enabled=${FINERACT_MANAGEMENT_PROMETHEUS_ENABLED:false}
# TODO: show pushgateway example
# management.prometheus.metrics.export.pushgateway.enabled=false
spring.cloud.aws.cloudwatch.enabled=${FINERACT_MANAGEMENT_CLOUDWATCH_ENABLED:false}
#spring.cloud.aws.cloudwatch.region=${FINERACT_MANAGEMENT_CLOUDWATCH_REGION:us-east-1}
management.metrics.export.cloudwatch.enabled=${FINERACT_MANAGEMENT_CLOUDWATCH_ENABLED:false}
management.metrics.export.cloudwatch.namespace=${FINERACT_MANAGEMENT_CLOUDWATCH_NAMESPACE:fineract}
management.metrics.export.cloudwatch.step=${FINERACT_MANAGEMENT_CLOUDWATCH_STEP:1m}
spring.autoconfigure.exclude=${FINERACT_AUTOCONFIGURE_EXCLUDE:io.awspring.cloud.autoconfigure.core.AwsAutoConfiguration,\
io.awspring.cloud.autoconfigure.core.CredentialsProviderAutoConfiguration}
spring.cloud.aws.endpoint=${FINERACT_AWS_ENDPOINT:}
spring.cloud.aws.region.static=${FINERACT_AWS_REGION_STATIC:us-east-1}
spring.cloud.aws.credentials.access-key=${FINERACT_AWS_CREDENTIALS_ACCESS_KEY:}
spring.cloud.aws.credentials.secret-key=${FINERACT_AWS_CREDENTIALS_SECRET_KEY:}
spring.cloud.aws.credentials.instance-profile=${FINERACT_AWS_CREDENTIALS_INSTANCE_PROFILE:false}
spring.cloud.aws.credentials.profile.name=${FINERACT_AWS_CREDENTIALS_PROFILE_NAME:}
spring.cloud.aws.credentials.profile.path=${FINERACT_AWS_CREDENTIALS_PROFILE_PATH:}
# FINERACT-914
server.forward-headers-strategy=framework
server.port=${FINERACT_SERVER_PORT:8443}
server.servlet.context-path=${FINERACT_SERVER_SERVLET_CONTEXT_PATH:/fineract-provider}
server.compression.enabled=${FINERACT_SERVER_COMPRESSION_ENABLED:true}
# Spring Boot strips the "message" field from a servlet-container-level error response by default
# (server.error.include-message defaults to "never"), so any rejection that happens before a request
# reaches Jersey -- most commonly TenantAwareBasicAuthenticationFilter's response.sendError() when
# Fineract-Platform-TenantId is missing or invalid -- rendered as a bare {timestamp,status,error,path}
# with no indication of what was actually wrong. Every other error path in this app (JAX-RS's own
# exception mappers) already carries a message; this makes the pre-Jersey filter layer consistent
# with that instead of the framework default.
server.error.include-message=always
server.ssl.enabled=${FINERACT_SERVER_SSL_ENABLED:true}
server.ssl.protocol=TLS
#server.ssl.ciphers=${FINERACT_SERVER_SSL_CIPHERS:TLS_RSA_WITH_AES_128_CBC_SHA256}
#server.ssl.enabled-protocols=${FINERACT_SERVER_SSL_PROTOCOLS:TLSv1.2}
server.ssl.key-store=${FINERACT_SERVER_SSL_KEY_STORE:classpath:keystore.jks}
server.ssl.key-store-password=${FINERACT_SERVER_SSL_KEY_STORE_PASSWORD:openmf}
# Graceful shutdown configuration
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=${FINERACT_TIMEOUT_PER_SHUTDOWN:30s}
server.tomcat.accept-count=${FINERACT_SERVER_TOMCAT_ACCEPT_COUNT:100}
server.tomcat.accesslog.enabled=${FINERACT_SERVER_TOMCAT_ACCESSLOG_ENABLED:false}
server.tomcat.max-connections=${FINERACT_SERVER_TOMCAT_MAX_CONNECTIONS:8192}
server.tomcat.max-http-form-post-size=${FINERACT_SERVER_TOMCAT_MAX_HTTP_FORM_POST_SIZE:2MB}
server.tomcat.max-keep-alive-requests=${FINERACT_SERVER_TOMCAT_MAX_KEEP_ALIVE_REQUESTS:100}
server.tomcat.threads.max=${FINERACT_SERVER_TOMCAT_THREADS_MAX:200}
server.tomcat.threads.min-spare=${FINERACT_SERVER_TOMCAT_THREADS_MIN_SPARE:10}
server.tomcat.mbeanregistry.enabled=${FINERACT_SERVER_TOMCAT_MBEANREGISTRY_ENABLED:false}
spring.datasource.hikari.driverClassName=${FINERACT_HIKARI_DRIVER_SOURCE_CLASS_NAME:org.postgresql.Driver}
spring.datasource.hikari.jdbcUrl=${FINERACT_HIKARI_JDBC_URL:jdbc:postgresql://localhost:5432/fineract_tenants}
spring.datasource.hikari.username=${FINERACT_HIKARI_USERNAME:postgres}
spring.datasource.hikari.password=${FINERACT_HIKARI_PASSWORD:313863}
spring.datasource.hikari.minimumIdle=${FINERACT_HIKARI_MINIMUM_IDLE:3}
spring.datasource.hikari.maximumPoolSize=${FINERACT_HIKARI_MAXIMUM_POOL_SIZE:10}
spring.datasource.hikari.idleTimeout=${FINERACT_HIKARI_IDLE_TIMEOUT:60000}
spring.datasource.hikari.connectionTimeout=${FINERACT_HIKARI_CONNECTION_TIMEOUT:20000}
spring.datasource.hikari.connectionTestquery=${FINERACT_HIKARI_TEST_QUERY:SELECT 1}
spring.datasource.hikari.autoCommit=${FINERACT_HIKARI_AUTO_COMMIT:true}
spring.datasource.hikari.transactionIsolation=${FINERACT_HIKARI_TRANSACTION_ISOLATION:TRANSACTION_REPEATABLE_READ}
spring.datasource.hikari.dataSourceProperties['cachePrepStmts']=${FINERACT_HIKARI_DS_PROPERTIES_CACHE_PREP_STMTS:true}
spring.datasource.hikari.dataSourceProperties['prepStmtCacheSize']=${FINERACT_HIKARI_DS_PROPERTIES_PREP_STMT_CACHE_SIZE:250}
spring.datasource.hikari.dataSourceProperties['prepStmtCacheSqlLimit']=${FINERACT_HIKARI_DS_PROPERTIES_PREP_STMT_CACHE_SQL_LIMIT:2048}
spring.datasource.hikari.dataSourceProperties['useServerPrepStmts']=${FINERACT_HIKARI_DS_PROPERTIES_USE_SERVER_PREP_STMTS:true}
spring.datasource.hikari.dataSourceProperties['useLocalSessionState']=${FINERACT_HIKARI_DS_PROPERTIES_USE_LOCAL_SESSION_STATE:true}
spring.datasource.hikari.dataSourceProperties['rewriteBatchedStatements']=${FINERACT_HIKARI_DS_PROPERTIES_REWRITE_BATCHED_STATEMENTS:true}
spring.datasource.hikari.dataSourceProperties['cacheResultSetMetadata']=${FINERACT_HIKARI_DS_PROPERTIES_CACHE_RESULT_SET_METADATA:true}
spring.datasource.hikari.dataSourceProperties['cacheServerConfiguration']=${FINERACT_HIKARI_DS_PROPERTIES_CACHE_SERVER_CONFIGURATION:true}
spring.datasource.hikari.dataSourceProperties['elideSetAutoCommits']=${FINERACT_HIKARI_DS_PROPERTIES_ELIDE_SET_AUTO_COMMITS:true}
spring.datasource.hikari.dataSourceProperties['maintainTimeStats']=${FINERACT_HIKARI_DS_PROPERTIES_MAINTAIN_TIME_STATS:false}
# https://github.com/brettwooldridge/HikariCP/wiki/JDBC-Logging#mysql-connectorj
# TODO FINERACT-890: <prop key="logger">com.mysql.cj.log.Slf4JLogger</prop>
spring.datasource.hikari.dataSourceProperties['logSlowQueries']=${FINERACT_HIKARI_DS_PROPERTIES_LOG_SLOW_QUERIES:true}
spring.datasource.hikari.dataSourceProperties['dumpQueriesOnException']=${FINERACT_HIKARI_DS_PROPERTIES_DUMP_QUERIES_IN_EXCEPTION:true}
spring.jpa.open-in-view=false
# Liquibase configuration
spring.liquibase.enabled=${FINERACT_LIQUIBASE_ENABLED:true}
spring.liquibase.changeLog=classpath:/db/changelog/db.changelog-master.xml
spring.liquibase.parameters.fineract.tenant.identifier=${fineract.tenant.identifier}
spring.liquibase.parameters.fineract.tenant.description=${fineract.tenant.description}
spring.liquibase.parameters.fineract.tenant.timezone=${fineract.tenant.timezone}
spring.liquibase.parameters.fineract.tenant.schema-name=${fineract.tenant.name}
spring.liquibase.parameters.fineract.tenant.host=${fineract.tenant.host}
spring.liquibase.parameters.fineract.tenant.port=${fineract.tenant.port}
spring.liquibase.parameters.fineract.tenant.username=${fineract.tenant.username}
spring.liquibase.parameters.fineract.tenant.password=${fineract.tenant.password}
spring.liquibase.parameters.fineract.tenant.parameters=${fineract.tenant.parameters}
spring.liquibase.parameters.fineract.tenant.read-only-host=${fineract.tenant.read-only-host}
spring.liquibase.parameters.fineract.tenant.read-only-port=${fineract.tenant.read-only-port}
spring.liquibase.parameters.fineract.tenant.read-only-username=${fineract.tenant.read-only-username}
spring.liquibase.parameters.fineract.tenant.read-only-password=${fineract.tenant.read-only-password}
spring.liquibase.parameters.fineract.tenant.read-only-parameters=${fineract.tenant.read-only-parameters}
spring.liquibase.parameters.fineract.tenant.read-only-name=${fineract.tenant.read-only-name}
spring.liquibase.parameters.fineract.tenant.rounding-mode=${fineract.tenant.config.rounding-mode}
springdoc.api-docs.path=${SPRINGDOC_API_DOCS_PATH:/api-docs}
springdoc.api-docs.enabled=${SPRINGDOC_API_DOCS_ENABLED:true}
springdoc.swagger-ui.enabled=${SPRINGDOC_SWAGGER_UI_ENABLED:true}
springdoc.swagger-ui.display-query-params=true
springdoc.swagger-ui.url=/fineract.json
springdoc.packagesToScan=org.apache.fineract
springdoc.pathsToMatch=/api/**
springdoc.use-management-port=${SPRINGDOC_USE_MANAGEMENT_PORT:false}
springdoc.show-actuator=${SPRINGDOC_SHOW_ACTUATOR:false}
spring.web.resources.static-locations=classpath:/static/
spring.main.allow-bean-definition-overriding=true
spring.task.scheduling.pool.size=4
spring.batch.initialize-schema=NEVER
# Disabling Spring Batch jobs on startup
spring.batch.job.enabled=false
fineract.retry.instances.executeCommand.max-attempts=${FINERACT_COMMAND_PROCESSING_RETRY_MAX_ATTEMPTS:3}
fineract.retry.instances.executeCommand.wait-duration=${FINERACT_COMMAND_PROCESSING_RETRY_WAIT_DURATION:1s}
fineract.retry.instances.executeCommand.enable-exponential-backoff=${FINERACT_COMMAND_PROCESSING_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
fineract.retry.instances.executeCommand.exponential-backoff-multiplier=${FINERACT_COMMAND_PROCESSING_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
fineract.retry.instances.executeCommand.retryExceptions=${FINERACT_COMMAND_PROCESSING_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException,org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessUnderProcessingException}
resilience4j.retry.instances.processJobDetailForExecution.max-attempts=${FINERACT_PROCESS_JOB_DETAIL_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.processJobDetailForExecution.wait-duration=${FINERACT_PROCESS_JOB_DETAIL_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.processJobDetailForExecution.enable-exponential-backoff=${FINERACT_PROCESS_JOB_DETAIL_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.processJobDetailForExecution.exponential-backoff-multiplier=${FINERACT_PROCESS_JOB_DETAIL_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.recalculateInterest.max-attempts=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.recalculateInterest.wait-duration=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.recalculateInterest.enable-exponential-backoff=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.recalculateInterest.exponential-backoff-multiplier=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.recalculateInterest.retryExceptions=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.postInterest.max-attempts=${FINERACT_PROCESS_POST_INTEREST_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.postInterest.wait-duration=${FINERACT_PROCESS_POST_INTEREST_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.postInterest.enable-exponential-backoff=${FINERACT_PROCESS_POST_INTEREST_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.postInterest.exponential-backoff-multiplier=${FINERACT_PROCESS_POST_INTEREST_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.postInterest.retryExceptions=${FINERACT_PROCESS_POST_INTEREST_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# business date
resilience4j.retry.instances.commandBusinessDateUpdate.max-attempts=${FINERACT_COMMAND_BUSINESS_DATE_UPDATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandBusinessDateUpdate.wait-duration=${FINERACT_COMMAND_BUSINESS_DATE_UPDATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandBusinessDateUpdate.enable-exponential-backoff=${FINERACT_COMMAND_BUSINESS_DATE_UPDATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandBusinessDateUpdate.exponential-backoff-multiplier=${FINERACT_COMMAND_BUSINESS_DATE_UPDATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandBusinessDateUpdate.retryExceptions=${FINERACT_COMMAND_BUSINESS_DATE_UPDATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# cache
resilience4j.retry.instances.commandCacheSwitch.max-attempts=${FINERACT_COMMAND_CACHE_SWITCH_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandCacheSwitch.wait-duration=${FINERACT_COMMAND_CACHE_SWITCH_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandCacheSwitch.enable-exponential-backoff=${FINERACT_COMMAND_CACHE_SWITCH_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandCacheSwitch.exponential-backoff-multiplier=${FINERACT_COMMAND_CACHE_SWITCH_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandCacheSwitch.retryExceptions=${FINERACT_COMMAND_CACHE_SWITCH_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# currency
resilience4j.retry.instances.commandCurrencyUpdate.max-attempts=${FINERACT_COMMAND_CURRENCY_UPDATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandCurrencyUpdate.wait-duration=${FINERACT_COMMAND_CURRENCY_UPDATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandCurrencyUpdate.enable-exponential-backoff=${FINERACT_COMMAND_CURRENCY_UPDATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandCurrencyUpdate.exponential-backoff-multiplier=${FINERACT_COMMAND_CURRENCY_UPDATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandCurrencyUpdate.retryExceptions=${FINERACT_COMMAND_CURRENCY_UPDATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# external event configuration
resilience4j.retry.instances.commandExternalEventConfigurationUpdate.max-attempts=${FINERACT_COMMAND_EXTERNAL_EVENT_CONFIGURATION_UPDATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandExternalEventConfigurationUpdate.wait-duration=${FINERACT_COMMAND_EXTERNAL_EVENT_CONFIGURATION_UPDATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandExternalEventConfigurationUpdate.enable-exponential-backoff=${FINERACT_COMMAND_EXTERNAL_EVENT_CONFIGURATION_UPDATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandExternalEventConfigurationUpdate.exponential-backoff-multiplier=${FINERACT_COMMAND_EXTERNAL_EVENT_CONFIGURATION_UPDATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandExternalEventConfigurationUpdate.retryExceptions=${FINERACT_COMMAND_EXTERNAL_EVENT_CONFIGURATION_UPDATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# note
resilience4j.retry.instances.commandNoteCreate.max-attempts=${FINERACT_COMMAND_NOTE_CREATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandNoteCreate.wait-duration=${FINERACT_COMMAND_NOTE_CREATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandNoteCreate.enable-exponential-backoff=${FINERACT_COMMAND_NOTE_CREATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandNoteCreate.exponential-backoff-multiplier=${FINERACT_COMMAND_NOTE_CREATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandNoteCreate.retryExceptions=${FINERACT_COMMAND_NOTE_CREATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.commandNoteUpdate.max-attempts=${FINERACT_COMMAND_NOTE_UPDATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandNoteUpdate.wait-duration=${FINERACT_COMMAND_NOTE_UPDATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandNoteUpdate.enable-exponential-backoff=${FINERACT_COMMAND_NOTE_UPDATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandNoteUpdate.exponential-backoff-multiplier=${FINERACT_COMMAND_NOTE_UPDATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandNoteUpdate.retryExceptions=${FINERACT_COMMAND_NOTE_UPDATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.commandNoteDelete.max-attempts=${FINERACT_COMMAND_NOTE_DELETE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandNoteDelete.wait-duration=${FINERACT_COMMAND_NOTE_DELETE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandNoteDelete.enable-exponential-backoff=${FINERACT_COMMAND_NOTE_DELETE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandNoteDelete.exponential-backoff-multiplier=${FINERACT_COMMAND_NOTE_DELETE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandNoteDelete.retryExceptions=${FINERACT_COMMAND_NOTE_DELETE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# document
resilience4j.retry.instances.commandDocumentCreate.max-attempts=${FINERACT_COMMAND_DOCUMENT_CREATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandDocumentCreate.wait-duration=${FINERACT_COMMAND_DOCUMENT_CREATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandDocumentCreate.enable-exponential-backoff=${FINERACT_COMMAND_DOCUMENT_CREATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandDocumentCreate.exponential-backoff-multiplier=${FINERACT_COMMAND_DOCUMENT_CREATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandDocumentCreate.retryExceptions=${FINERACT_COMMAND_DOCUMENT_CREATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.commandDocumentUpdate.max-attempts=${FINERACT_COMMAND_DOCUMENT_UPDATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandDocumentUpdate.wait-duration=${FINERACT_COMMAND_DOCUMENT_UPDATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandDocumentUpdate.enable-exponential-backoff=${FINERACT_COMMAND_DOCUMENT_UPDATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandDocumentUpdate.exponential-backoff-multiplier=${FINERACT_COMMAND_DOCUMENT_UPDATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandDocumentUpdate.retryExceptions=${FINERACT_COMMAND_DOCUMENT_UPDATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.commandDocumentDelete.max-attempts=${FINERACT_COMMAND_DOCUMENT_DELETE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandDocumentDelete.wait-duration=${FINERACT_COMMAND_DOCUMENT_DELETE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandDocumentDelete.enable-exponential-backoff=${FINERACT_COMMAND_DOCUMENT_DELETE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandDocumentDelete.exponential-backoff-multiplier=${FINERACT_COMMAND_DOCUMENT_DELETE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandDocumentDelete.retryExceptions=${FINERACT_COMMAND_DOCUMENT_DELETE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# image
resilience4j.retry.instances.commandImageCreate.max-attempts=${FINERACT_COMMAND_IMAGE_CREATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandImageCreate.wait-duration=${FINERACT_COMMAND_IMAGE_CREATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandImageCreate.enable-exponential-backoff=${FINERACT_COMMAND_IMAGE_CREATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandImageCreate.exponential-backoff-multiplier=${FINERACT_COMMAND_IMAGE_CREATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandImageCreate.retryExceptions=${FINERACT_COMMAND_IMAGE_CREATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.commandImageDelete.max-attempts=${FINERACT_COMMAND_IMAGE_DELETE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandImageDelete.wait-duration=${FINERACT_COMMAND_IMAGE_DELETE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandImageDelete.enable-exponential-backoff=${FINERACT_COMMAND_IMAGE_DELETE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandImageDelete.exponential-backoff-multiplier=${FINERACT_COMMAND_IMAGE_DELETE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandImageDelete.retryExceptions=${FINERACT_COMMAND_IMAGE_DELETE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# payment type
resilience4j.retry.instances.commandPaymentTypeCreate.max-attempts=${FINERACT_COMMAND_PAYMENT_TYPE_CREATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandPaymentTypeCreate.wait-duration=${FINERACT_COMMAND_PAYMENT_TYPE_CREATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandPaymentTypeCreate.enable-exponential-backoff=${FINERACT_COMMAND_PAYMENT_TYPE_CREATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandPaymentTypeCreate.exponential-backoff-multiplier=${FINERACT_COMMAND_PAYMENT_TYPE_CREATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandPaymentTypeCreate.retryExceptions=${FINERACT_COMMAND_PAYMENT_TYPE_CREATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.commandPaymentTypeUpdate.max-attempts=${FINERACT_COMMAND_PAYMENT_TYPE_UPDATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandPaymentTypeUpdate.wait-duration=${FINERACT_COMMAND_PAYMENT_TYPE_UPDATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandPaymentTypeUpdate.enable-exponential-backoff=${FINERACT_COMMAND_PAYMENT_TYPE_UPDATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandPaymentTypeUpdate.exponential-backoff-multiplier=${FINERACT_COMMAND_PAYMENT_TYPE_UPDATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandPaymentTypeUpdate.retryExceptions=${FINERACT_COMMAND_PAYMENT_TYPE_UPDATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.commandPaymentTypeDelete.max-attempts=${FINERACT_COMMAND_PAYMENT_TYPE_DELETE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandPaymentTypeDelete.wait-duration=${FINERACT_COMMAND_PAYMENT_TYPE_DELETE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandPaymentTypeDelete.enable-exponential-backoff=${FINERACT_COMMAND_PAYMENT_TYPE_DELETE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandPaymentTypeDelete.exponential-backoff-multiplier=${FINERACT_COMMAND_PAYMENT_TYPE_DELETE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandPaymentTypeDelete.retryExceptions=${FINERACT_COMMAND_PAYMENT_TYPE_DELETE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# mix taxonomy
resilience4j.retry.instances.commandMixTaxonomyMappingUpdate.max-attempts=${FINERACT_COMMAND_MIX_TAXONOMY_MAPPING_UPDATE_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandMixTaxonomyMappingUpdate.wait-duration=${FINERACT_COMMAND_MIX_TAXONOMY_MAPPING_UPDATE_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandMixTaxonomyMappingUpdate.enable-exponential-backoff=${FINERACT_COMMAND_MIX_TAXONOMY_MAPPING_UPDATE_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandMixTaxonomyMappingUpdate.exponential-backoff-multiplier=${FINERACT_COMMAND_MIX_TAXONOMY_MAPPING_UPDATE_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandMixTaxonomyMappingUpdate.retryExceptions=${FINERACT_COMMAND_MIX_TAXONOMY_MAPPING_UPDATE_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# command
fineract.command.enabled=true
fineract.command.executor=${FINERACT_COMMAND_EXECUTOR:sync}
fineract.command.ring-buffer-size=${FINERACT_COMMAND_RING_BUFFER_SIZE:1024}
fineract.command.producer-type=${FINERACT_COMMAND_PRODUCER_TYPE:single}
fineract.command.auditable=${FINERACT_COMMAND_AUDITABLE:true}
# this is duplicated on purpose to keep fineract-command independent; once all modules are migrated we clean up
fineract.command.idempotency-key-header-name=${FINERACT_IDEMPOTENCY_KEY_HEADER_NAME:Idempotency-Key}
fineract.command.file-dead-letter-queue-enabled=${FINERACT_FILE_DEAD_LETTER_QUEUE_ENABLED:false}
fineract.command.file-dead-letter-queue-path=${FINERACT_FILE_DEAD_LETTER_QUEUE_PATH:/tmp/fineract-command-audit}
resilience4j.retry.instances.commandAuditProcessing.max-attempts=${FINERACT_COMMAND_AUDIT_PROCESSING_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandAuditProcessing.wait-duration=${FINERACT_COMMAND_AUDIT_PROCESSING_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandAuditProcessing.enable-exponential-backoff=${FINERACT_COMMAND_AUDIT_PROCESSING_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandAuditProcessing.exponential-backoff-multiplier=${FINERACT_COMMAND_AUDIT_PROCESSING_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandAuditProcessing.retryExceptions=${FINERACT_COMMAND_AUDIT_PROCESSING_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.commandAuditProcessed.max-attempts=${FINERACT_COMMAND_AUDIT_PROCESSED_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandAuditProcessed.wait-duration=${FINERACT_COMMAND_AUDIT_PROCESSED_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandAuditProcessed.enable-exponential-backoff=${FINERACT_COMMAND_AUDIT_PROCESSED_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandAuditProcessed.exponential-backoff-multiplier=${FINERACT_COMMAND_AUDIT_PROCESSED_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandAuditProcessed.retryExceptions=${FINERACT_COMMAND_AUDIT_PROCESSED_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.commandAuditError.max-attempts=${FINERACT_COMMAND_AUDIT_ERROR_RETRY_MAX_ATTEMPTS:3}
resilience4j.retry.instances.commandAuditError.wait-duration=${FINERACT_COMMAND_AUDIT_ERROR_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandAuditError.enable-exponential-backoff=${FINERACT_COMMAND_AUDIT_ERROR_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandAuditError.exponential-backoff-multiplier=${FINERACT_COMMAND_AUDIT_ERROR_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandAuditError.retryExceptions=${FINERACT_COMMAND_AUDIT_ERROR_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
resilience4j.retry.instances.commandAuditFallback.max-attempts=${FINERACT_COMMAND_AUDIT_FALLBACK_RETRY_MAX_ATTEMPTS:1}
resilience4j.retry.instances.commandAuditFallback.wait-duration=${FINERACT_COMMAND_AUDIT_FALLBACK_RETRY_WAIT_DURATION:1s}
resilience4j.retry.instances.commandAuditFallback.enable-exponential-backoff=${FINERACT_COMMAND_AUDIT_FALLBACK_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
resilience4j.retry.instances.commandAuditFallback.exponential-backoff-multiplier=${FINERACT_COMMAND_AUDIT_FALLBACK_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
resilience4j.retry.instances.commandAuditFallback.retryExceptions=${FINERACT_COMMAND_AUDIT_FALLBACK_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
# ── LincPay eKYC API ──────────────────────────────────────────────────────────
# Set FINERACT_KYC_LINCPAY_API_KEY and FINERACT_KYC_LINCPAY_SECRET as env vars
# in production. Never commit real credentials to source control.
fineract.kyc.lincpay.api-key=${FINERACT_KYC_LINCPAY_API_KEY:api_7c9e3a1f6d4b2a8c5e1f3d7b9a2c6e4f}
fineract.kyc.lincpay.secret=${FINERACT_KYC_LINCPAY_SECRET:secret_4e8a2d7c1f9b3a6e5d2c8f1a7b4e9c3d}
fineract.kyc.lincpay.base-url=${FINERACT_KYC_LINCPAY_BASE_URL:https://ekyc.lincpay.in/EKYC/ekyc}
fineract.kyc.lincpay.path.aadhaar-generate-otp=${FINERACT_KYC_LINCPAY_PATH_AADHAAR_GENERATE_OTP:/aadhaar/generate-otp}
fineract.kyc.lincpay.path.aadhaar-verify-otp=${FINERACT_KYC_LINCPAY_PATH_AADHAAR_VERIFY_OTP:/aadhaar/verify-otp}
fineract.kyc.lincpay.path.pan-validate=${FINERACT_KYC_LINCPAY_PATH_PAN_VALIDATE:/validate-pan}
fineract.kyc.lincpay.path.gstin-validate=${FINERACT_KYC_LINCPAY_PATH_GSTIN_VALIDATE:/validate-gstn}
fineract.kyc.lincpay.path.cin-validate=${FINERACT_KYC_LINCPAY_PATH_CIN_VALIDATE:/validate-company}
fineract.kyc.lincpay.path.din-validate=${FINERACT_KYC_LINCPAY_PATH_DIN_VALIDATE:/validate-director}
# ── OpenProject Integration ──────────────────────────────────────────────────
# Set FINERACT_OPENPROJECT_API_TOKEN as env var in production.
fineract.openproject.enabled=${FINERACT_OPENPROJECT_ENABLED:true}
fineract.openproject.base-url=${FINERACT_OPENPROJECT_BASE_URL:https://Sm.godemo.in}
fineract.openproject.project-id=${FINERACT_OPENPROJECT_PROJECT_ID:cbsnexora}
fineract.openproject.api-token=${FINERACT_OPENPROJECT_API_TOKEN:57dd9f933f113c7274e3ed3d5ca82e1e45e040c857160975087694f4d39ff596}
# ── DIP / MNRL Mobile Number Lookup ──────────────────────────────────────────
# Checks a mobile number against the DoT Digital Intelligence Platform (suspected numbers) and the
# Mobile Number Revocation List (disconnected numbers). The backend calls
# GET {base-url}/api/v1/lookup/check?mobileNumber=... and expects the response shape documented in
# MobileLookupResult.
#
# A number that cannot be checked is NOT treated as clean: an unreachable service is recorded as
# SERVICE_UNAVAILABLE and the officer must either reject the number or record a written reason to
# proceed. So a wrong base-url here does not silently wave numbers through — it stops onboarding.
# ┌──────────────────────────────────────────────────────────────────────────┐
# │ LOCAL TEST LOOKUP SERVICE — NOT THE REAL DoT DIP/MNRL ENDPOINT. │
# │ │
# │ This default points at scripts/mock-dip-lookup-service.js on localhost │
# │ so onboarding can be demonstrated end to end. Its verdicts are invented; │
# │ NO NUMBER IS ACTUALLY CHECKED AGAINST THE DoT. Every response carries │
# │ provider=MOCK_DIP_LOOKUP_TEST_ONLY, which is stored in the lookup log's │
# │ raw response so a mock check can never be mistaken for a real one. │
# │ │
# │ node scripts/mock-dip-lookup-service.js │
# │ │
# │ BEFORE PRODUCTION: set FINERACT_MOBILE_LOOKUP_BASE_URL to the real │
# │ DIP/MNRL provider. Do not ship the mock. │
# └──────────────────────────────────────────────────────────────────────────┘
fineract.mobile-lookup.base-url=${FINERACT_MOBILE_LOOKUP_BASE_URL:http://127.0.0.1:8090}
# Set to false to skip the DIP/MNRL check entirely (no HTTP call at all, no need to run the mock
# service) -- every number is then logged as CLEAN but stamped "LOOKUP_DISABLED_BY_CONFIG" so it is
# never mistaken for a real pass.
# Currently OFF by default for local work so nobody needs the mock service running. Set
# FINERACT_MOBILE_LOOKUP_ENABLED=true (or flip the default below) before UAT/production, where the
# check must actually run.
fineract.mobile-lookup.enabled=${FINERACT_MOBILE_LOOKUP_ENABLED:false}
# ── Login OTP (2FA) — uses LincPay credentials above ─────────────────────────
fineract.security.otp.lincpay.generate-path=${FINERACT_OTP_LINCPAY_GENERATE_PATH:/mobile/generate-otp}
fineract.security.otp.lincpay.verify-path=${FINERACT_OTP_LINCPAY_VERIFY_PATH:/verify-mobile-otp}
fineract.security.otp.ttl-seconds=${FINERACT_OTP_TTL_SECONDS:300}
fineract.security.otp.max-attempts=${FINERACT_OTP_MAX_ATTEMPTS:5}
# ── Spring Mail (email OTP, alerts, password reset) ──────────────────────────
# IMPORTANT: the password below is a Gmail App Password (NOT the account password).
# Keep env-var override for prod — set SPRING_MAIL_PASSWORD in production environments.
spring.mail.host=${SPRING_MAIL_HOST:smtp.gmail.com}
spring.mail.port=${SPRING_MAIL_PORT:587}
spring.mail.username=${SPRING_MAIL_USERNAME:inform.notifications@gmail.com}
spring.mail.password=${SPRING_MAIL_PASSWORD:vjvgdqxsivbipefw}
spring.mail.properties.mail.smtp.auth=${SPRING_MAIL_SMTP_AUTH:true}
spring.mail.properties.mail.smtp.starttls.enable=${SPRING_MAIL_STARTTLS:true}
spring.mail.properties.mail.transport.protocol=smtp
fineract.email.from-address=${FINERACT_EMAIL_FROM_ADDRESS:no-reply@cbsnexora.com}
fineract.email.from-name=${FINERACT_EMAIL_FROM_NAME:CBSnexora}
fineract.email.support-address=${FINERACT_EMAIL_SUPPORT_ADDRESS:support@cbsnexora.com}
# ── Customer notification gateways (KYC exception outreach) ──────────────────
# Used by the "Log Customer Contact" action on the KYC Exceptions screen: choosing SMS, Email or
# WhatsApp transmits a notice to the customer and records the delivery outcome on the contact log.
#
# Email needs no configuration here — it uses the spring.mail.* SMTP settings above.
#
# SMS and WhatsApp are vendor-agnostic: the request shape is described by properties so switching
# gateway is a config change. `body-template` supports {{destination}}, {{message}}, {{senderId}}
# and {{templateId}}; values are escaped for the configured content-type at send time.
# Both are DISABLED by default — a channel that is off records the attempt and reports
# "not sent, no gateway configured" rather than silently claiming success.
#
# NOTE: this is NOT the LincPay eKYC endpoint used for login OTP above. That endpoint mints an OTP
# of its own and cannot carry an arbitrary message; point these at a real send-message API.
#
# Example (MSG91 transactional SMS):
# fineract.notification.sms.base-url=https://control.msg91.com
# fineract.notification.sms.path=/api/v5/flow/
# fineract.notification.sms.auth-header-name=authkey
# fineract.notification.sms.auth-header-value=<your authkey>
# fineract.notification.sms.body-template={"template_id":"{{templateId}}","short_url":"0",\
# "recipients":[{"mobiles":"{{destination}}","MESSAGE":"{{message}}"}]}
# fineract.notification.sms.reference-json-path=data.messageId
# ┌──────────────────────────────────────────────────────────────────────────┐
# │ LOCAL TEST GATEWAY — NOT A REAL SMS PROVIDER. │
# │ │
# │ These defaults point at scratchpad/mock-sms-gateway.js on localhost so │
# │ the outreach flow can be demonstrated end to end. NOTHING REACHES A │
# │ PHONE. Every contact-log row records provider=MOCK_SMS_GATEWAY_TEST_ONLY │
# │ so a mock send can never be mistaken for a real delivery in the audit │
# │ trail. │
# │ │
# │ BEFORE PRODUCTION: set FINERACT_NOTIFICATION_SMS_* to the real gateway, │
# │ or set FINERACT_NOTIFICATION_SMS_ENABLED=false. Do not ship the mock. │
# └──────────────────────────────────────────────────────────────────────────┘
fineract.notification.sms.enabled=${FINERACT_NOTIFICATION_SMS_ENABLED:true}
fineract.notification.sms.provider=${FINERACT_NOTIFICATION_SMS_PROVIDER:MOCK_SMS_GATEWAY_TEST_ONLY}
fineract.notification.sms.base-url=${FINERACT_NOTIFICATION_SMS_BASE_URL:http://127.0.0.1:9797}
fineract.notification.sms.path=${FINERACT_NOTIFICATION_SMS_PATH:/send}
fineract.notification.sms.auth-header-name=${FINERACT_NOTIFICATION_SMS_AUTH_HEADER_NAME:Authorization}
fineract.notification.sms.auth-header-value=${FINERACT_NOTIFICATION_SMS_AUTH_HEADER_VALUE:mock-test-key}
fineract.notification.sms.content-type=${FINERACT_NOTIFICATION_SMS_CONTENT_TYPE:application/json}
fineract.notification.sms.body-template=${FINERACT_NOTIFICATION_SMS_BODY_TEMPLATE:{"mobileNumber":"{{destination}}","message":"{{message}}","senderId":"{{senderId}}","templateId":"{{templateId}}"\}}
# DLT-registered sender ID and template ID — TRAI requires both for transactional SMS in India.
fineract.notification.sms.sender-id=${FINERACT_NOTIFICATION_SMS_SENDER_ID:}
fineract.notification.sms.template-id=${FINERACT_NOTIFICATION_SMS_TEMPLATE_ID:}
fineract.notification.sms.reference-json-path=${FINERACT_NOTIFICATION_SMS_REFERENCE_JSON_PATH:data.messageId}
# Example (Meta WhatsApp Cloud API):
# fineract.notification.whatsapp.base-url=https://graph.facebook.com
# fineract.notification.whatsapp.path=/v21.0/<phone-number-id>/messages
# fineract.notification.whatsapp.auth-header-value=Bearer <access token>
# fineract.notification.whatsapp.body-template={"messaging_product":"whatsapp",\
# "to":"{{destination}}","type":"text","text":{"body":"{{message}}"}}
# fineract.notification.whatsapp.reference-json-path=messages.0.id
# Business-initiated messages outside the 24h service window must use an approved template, so a
# KYC notice will normally need the template-shaped body rather than the plain "text" one above.
# Also pointed at the LOCAL TEST GATEWAY above — see that banner. Nothing reaches WhatsApp.
fineract.notification.whatsapp.enabled=${FINERACT_NOTIFICATION_WHATSAPP_ENABLED:true}
fineract.notification.whatsapp.provider=${FINERACT_NOTIFICATION_WHATSAPP_PROVIDER:MOCK_WHATSAPP_GATEWAY_TEST_ONLY}
fineract.notification.whatsapp.base-url=${FINERACT_NOTIFICATION_WHATSAPP_BASE_URL:http://127.0.0.1:9797}
fineract.notification.whatsapp.path=${FINERACT_NOTIFICATION_WHATSAPP_PATH:/send}
fineract.notification.whatsapp.auth-header-name=${FINERACT_NOTIFICATION_WHATSAPP_AUTH_HEADER_NAME:Authorization}
fineract.notification.whatsapp.auth-header-value=${FINERACT_NOTIFICATION_WHATSAPP_AUTH_HEADER_VALUE:mock-test-key}
fineract.notification.whatsapp.content-type=${FINERACT_NOTIFICATION_WHATSAPP_CONTENT_TYPE:application/json}
fineract.notification.whatsapp.body-template=${FINERACT_NOTIFICATION_WHATSAPP_BODY_TEMPLATE:{"to":"{{destination}}","message":"{{message}}"\}}
fineract.notification.whatsapp.sender-id=${FINERACT_NOTIFICATION_WHATSAPP_SENDER_ID:}
fineract.notification.whatsapp.template-id=${FINERACT_NOTIFICATION_WHATSAPP_TEMPLATE_ID:}
fineract.notification.whatsapp.reference-json-path=${FINERACT_NOTIFICATION_WHATSAPP_REFERENCE_JSON_PATH:data.messageId}
fineract.notification.whatsapp.country-code=${FINERACT_NOTIFICATION_WHATSAPP_COUNTRY_CODE:91}
# Days the customer is given to complete KYC, quoted in the notice body.
fineract.notification.kyc-contact.response-days=${FINERACT_NOTIFICATION_KYC_RESPONSE_DAYS:15}
# Frontend base URL — used for email links (voting, etc.)
cbs.frontend.base-url=${CBS_FRONTEND_BASE_URL:https://cbs.godemo.in}
# ── NPCI Clearing House Integration ──────────────────────────────────────────
# Real, separate NPCI service (see /npci-clearing-house) — this CBS registers itself as a bank there
# (its own key pair, generated locally, only the public half is ever sent) and submits outward CTS
# batches to it. NPCI's own public key is fetched live via GET {base-url}/npci/public-key, never configured
# here — no key material is ever copy-pasted between the two services.
fineract.npci.base-url=${FINERACT_NPCI_BASE_URL:http://localhost:8444}
fineract.npci.bank-code=${FINERACT_NPCI_BANK_CODE:CBSHOME01}
fineract.npci.bank-name=${FINERACT_NPCI_BANK_NAME:CBSnexora Home Bank}
fineract.npci.ifsc-prefix=${FINERACT_NPCI_IFSC_PREFIX:CBSH}
# Where NPCI can push routed packages destined for this bank: POST /api/v1/npci/inward-push. NOTE this
# Fineract fork identifies the tenant via the Fineract-Platform-TenantId HEADER, not a URL path segment —
# there is no "/default/" (or any tenant) segment in the path itself; NPCI's push client must send that
# header (defaults to "default", the only tenant this dev setup has).
# ALSO NOTE: CBS's own HTTPS certificate is self-signed in this dev setup — NPCI's JDK HttpClient will fail
# TLS validation against it unless NPCI is separately configured to trust it. Until then, pushes here
# will fail and NPCI gracefully falls back to the poll model (GET /clearing/inward/{bankCode}).
fineract.npci.inward-callback-url=${FINERACT_NPCI_INWARD_CALLBACK_URL:https://localhost:8443/fineract-provider/api/v1/npci/inward-push}
fineract.npci.timeout-ms=${FINERACT_NPCI_TIMEOUT_MS:10000}