feat(clearing): add CTS/NACH clearing modules with real NPCI integration
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Canceled after 0s
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Canceled after 0s
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Canceled after 0s
Fineract Documentation build / build (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Canceled after 0s
Fineract Liquibase Only mode - PostgreSQL / test (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, build-core) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (main, cucumber) (push) Canceled after 0s
Fineract Build & Cucumber tests (without E2E tests) / verify (progressive-loan, build-progressive-loan) (push) Canceled after 0s
Fineract Docker Builds / build (false, docker-compose-postgresql.yml, postgresql) (push) Canceled after 0s
Fineract Docker Builds / build (true, docker-compose.yml, mariadb) (push) Canceled after 0s
Fineract Documentation build / build (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 1 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 10 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 2 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 3 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 4 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 5 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 6 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 7 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 8 of 10) (push) Canceled after 0s
Fineract E2E Tests / E2E Tests (Shard 9 of 10) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MariaDB / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - MySQL / test (test-core-5) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-1) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-2) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-3) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-4) (push) Canceled after 0s
Fineract Cargo & Unit- & Integration tests - PostgreSQL / test (test-core-5) (push) Canceled after 0s
Fineract Liquibase Only mode - PostgreSQL / test (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with ActiveMQ (push) Canceled after 0s
Fineract Messaging Smoke Tests / Smoke Test with Kafka (push) Canceled after 0s
- Inward/outward CTS clearing (capture, validate, settle, dishonour), positive pay, settlement/reconciliation, and NACH clearing modules - Real, separate NPCI clearing-house integration: hybrid RSA+AES envelope crypto, bank self-registration, outward batch submission, and an inward push webhook - Outward clearing is now session-batched: a 2-hourly scheduled job (plus the existing manual "Send Pending Batch" fallback) bundles CAPTURED cheques instead of sending them one at a time - Batch-summary read APIs and date/text filters across inward batches, outward presentments, and outward batches Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
383dfdc6e9
commit
b433edfdfe
@@ -690,3 +690,22 @@ fineract.email.support-address=${FINERACT_EMAIL_SUPPORT_ADDRESS:support@cbsnexor
|
||||
|
||||
# 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}
|
||||
|
||||
@@ -410,4 +410,27 @@
|
||||
<include file="parts/0387_chequeleaf_serial_unique_per_lot.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0388_chequeleaf_returned_status.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0389_chequebook_pending_request_hold.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0390_clearing_shared_reference.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0391_cts_inward_clearing.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0392_cts_outward_clearing.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0393_clearing_settlement_reconciliation.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0394_nach_clearing.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0395_clearing_permissions.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0396_cts_cheque_image_iqa.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0397_positive_pay_system.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0398_outward_npci_envelope.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0399_outward_cts_file.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0400_outward_iqa_stoppayment.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0401_outward_cts_missing_fields.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0402_outward_send_batch_permission.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0403_outward_clearing_batch_job.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0404_cts_cheque_image_store.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0405_cts_npci_inward_package.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0406_clearing_crypto_audit.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0407_remove_clearing_crypto_simulation.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0408_clearing_own_npci_identity.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0409_outward_npci_response.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0410_npci_inward_push_log.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0411_inward_item_source_details.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0412_activate_outward_clearing_batch_job.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Shared reference data for the CTS + NACH clearing modules:
|
||||
- m_clearing_bank : the (simulated) clearing network's banks and their RSA key pairs
|
||||
- m_clearing_return_reason_code : standardized return/dishonour codes (spec section 14), shared CTS+NACH
|
||||
- m_clearing_gl_config : maps clearing suspense/settlement roles to GL accounts (admin-configured)
|
||||
- m_clearing_notification : simulated SMS/email log for pass/return/settlement events
|
||||
|
||||
Bank rows are NOT seeded here because each needs a real RSA key pair generated at runtime by
|
||||
ClearingCryptoService; they are created via POST /v1/clearing/banks (or the one-shot bootstrap action).
|
||||
Reason codes ARE seeded (idempotently) so decisioning dropdowns work out of the box.
|
||||
|
||||
Every changeSet is guarded so this migration is a safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0390-clearing-bank" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_clearing_bank"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_clearing_bank">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="bank_name" type="VARCHAR(150)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="ifsc_prefix" type="VARCHAR(20)">
|
||||
<constraints nullable="false" unique="true" uniqueConstraintName="uk_clearing_bank_ifsc_prefix"/>
|
||||
</column>
|
||||
<column name="role" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="public_key" type="TEXT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="private_key" type="TEXT"/>
|
||||
<column name="is_active" type="BOOLEAN" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0390-clearing-return-reason-code" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_clearing_return_reason_code"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_clearing_return_reason_code">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="code" type="VARCHAR(10)">
|
||||
<constraints nullable="false" unique="true" uniqueConstraintName="uk_clearing_return_reason_code"/>
|
||||
</column>
|
||||
<column name="description" type="VARCHAR(200)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="category" type="VARCHAR(20)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="applies_to" type="VARCHAR(10)" defaultValue="BOTH">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="is_active" type="BOOLEAN" defaultValueBoolean="true">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0390-clearing-return-reason-code-seed" author="CBS" runOnChange="false">
|
||||
<sql>
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '01', 'Insufficient Funds', 'FINANCIAL', 'BOTH', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '01');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '02', 'Payment Stopped by Drawer', 'INSTRUMENT', 'CTS', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '02');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '03', 'Account Closed', 'ACCOUNT', 'BOTH', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '03');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '04', 'Signature Differs / Mismatch', 'SIGNATURE', 'CTS', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '04');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '05', 'Alteration Requires Drawer''s Authentication', 'INSTRUMENT', 'CTS', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '05');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '06', 'Amount in Words and Figures Differ', 'INSTRUMENT', 'CTS', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '06');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '07', 'Post Dated / Stale Cheque', 'INSTRUMENT', 'CTS', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '07');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '08', 'Refer to Drawer', 'ACCOUNT', 'CTS', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '08');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '09', 'No Such Account', 'ACCOUNT', 'BOTH', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '09');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '10', 'Account Frozen / Dormant', 'ACCOUNT', 'BOTH', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '10');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '11', 'Image Quality (IQA) Failure', 'TECHNICAL', 'CTS', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '11');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '12', 'Duplicate Presentment', 'TECHNICAL', 'BOTH', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '12');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '20', 'Mandate Not Registered', 'MANDATE', 'NACH', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '20');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '21', 'Mandate Expired or Cancelled', 'MANDATE', 'NACH', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '21');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '22', 'Amount Exceeds Mandate Limit', 'MANDATE', 'NACH', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '22');
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '99', 'Other (see remarks)', 'OTHER', 'BOTH', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '99');
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0390-clearing-gl-config" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_clearing_gl_config"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_clearing_gl_config">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="config_key" type="VARCHAR(50)">
|
||||
<constraints nullable="false" unique="true" uniqueConstraintName="uk_clearing_gl_config_key"/>
|
||||
</column>
|
||||
<column name="description" type="VARCHAR(200)"/>
|
||||
<column name="gl_account_id" type="BIGINT">
|
||||
<constraints foreignKeyName="fk_clearing_gl_config_gl" references="acc_gl_account(id)"/>
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0390-clearing-gl-config-seed" author="CBS" runOnChange="false">
|
||||
<sql>
|
||||
INSERT INTO m_clearing_gl_config (config_key, description, gl_account_id)
|
||||
SELECT 'CTS_INWARD_SUSPENSE', 'CTS inward clearing suspense (paying side)', NULL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_gl_config WHERE config_key = 'CTS_INWARD_SUSPENSE');
|
||||
INSERT INTO m_clearing_gl_config (config_key, description, gl_account_id)
|
||||
SELECT 'CTS_OUTWARD_SUSPENSE', 'CTS outward clearing suspense (collecting side)', NULL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_gl_config WHERE config_key = 'CTS_OUTWARD_SUSPENSE');
|
||||
INSERT INTO m_clearing_gl_config (config_key, description, gl_account_id)
|
||||
SELECT 'NACH_SUSPENSE', 'NACH clearing suspense', NULL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_gl_config WHERE config_key = 'NACH_SUSPENSE');
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0390-clearing-notification" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_clearing_notification"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_clearing_notification">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="channel" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="recipient" type="VARCHAR(150)"/>
|
||||
<column name="event" type="VARCHAR(30)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="clearing_type" type="VARCHAR(10)"/>
|
||||
<column name="ref_type" type="VARCHAR(40)"/>
|
||||
<column name="ref_id" type="BIGINT"/>
|
||||
<column name="message" type="VARCHAR(1000)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="status" type="VARCHAR(15)" defaultValue="SIMULATED">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
CTS inward clearing: a batch (session) of cheques drawn on THIS bank, received (simulated) from the
|
||||
clearing house, and the individual items within it. Each item carries its captured MICR data, the
|
||||
result of every validation rule, and the pass/return decision. An item links to an existing
|
||||
m_cheque_leaf where one matches (by cheque number + account), so a pass/return can drive that leaf's
|
||||
USED/RETURNED status. Safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0391-inward-clearing-batch" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_inward_clearing_batch"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_inward_clearing_batch">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="batch_reference" type="VARCHAR(100)">
|
||||
<constraints nullable="false" unique="true" uniqueConstraintName="uk_inward_clearing_batch_ref"/>
|
||||
</column>
|
||||
<column name="session_date" type="DATE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="presentment_type" type="VARCHAR(10)" defaultValue="MICR">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="source_file" type="VARCHAR(200)"/>
|
||||
<column name="inward_envelope" type="TEXT"/>
|
||||
<column name="total_item_count" type="INTEGER" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="total_amount" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="status" type="VARCHAR(15)" defaultValue="RECEIVED">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="office_id" type="BIGINT"/>
|
||||
<column name="received_by" type="BIGINT"/>
|
||||
<column name="received_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="validated_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="decisioned_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="settled_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="version" type="INTEGER" defaultValueNumeric="0"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0391-inward-clearing-item" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_inward_clearing_item"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_inward_clearing_item">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="batch_id" type="BIGINT">
|
||||
<constraints nullable="false" foreignKeyName="fk_inward_item_batch" references="m_inward_clearing_batch(id)"/>
|
||||
</column>
|
||||
<column name="cheque_leaf_id" type="BIGINT">
|
||||
<constraints nullable="true" foreignKeyName="fk_inward_item_leaf" references="m_cheque_leaf(id)"/>
|
||||
</column>
|
||||
<column name="account_type" type="VARCHAR(10)"/>
|
||||
<column name="account_id" type="BIGINT"/>
|
||||
<column name="cheque_number" type="VARCHAR(25)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="micr_code" type="VARCHAR(20)"/>
|
||||
<column name="ifsc" type="VARCHAR(15)"/>
|
||||
<column name="payee_name" type="VARCHAR(150)"/>
|
||||
<column name="amount" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="amount_in_words" type="VARCHAR(300)"/>
|
||||
<column name="instrument_date" type="DATE"/>
|
||||
<column name="presented_date" type="DATE"/>
|
||||
<!-- validation results: nullable Boolean = not-yet-checked; signature_ok null = not manually reviewed -->
|
||||
<column name="account_check_passed" type="BOOLEAN"/>
|
||||
<column name="balance_check_passed" type="BOOLEAN"/>
|
||||
<column name="signature_ok" type="BOOLEAN"/>
|
||||
<column name="duplicate_check_passed" type="BOOLEAN"/>
|
||||
<column name="stop_payment_check_passed" type="BOOLEAN"/>
|
||||
<column name="amount_words_figures_match" type="BOOLEAN"/>
|
||||
<column name="stale_or_postdated" type="BOOLEAN"/>
|
||||
<column name="validation_detail" type="VARCHAR(1000)"/>
|
||||
<!-- decision -->
|
||||
<column name="decision" type="VARCHAR(10)" defaultValue="PENDING">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="return_reason_code" type="VARCHAR(10)"/>
|
||||
<column name="decision_reason" type="VARCHAR(500)"/>
|
||||
<column name="decisioned_by" type="BIGINT"/>
|
||||
<column name="decisioned_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="item_status" type="VARCHAR(15)" defaultValue="RECEIVED">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="hold_placed" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="hold_amount" type="DECIMAL(19,6)"/>
|
||||
<column name="settlement_batch_id" type="BIGINT"/>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="version" type="INTEGER" defaultValueNumeric="0"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
CTS outward clearing: cheques our own customers deposited that are drawn on OTHER banks, captured for
|
||||
onward presentation to the clearing house. A flat entity (no batch/item split needed per spec) with a
|
||||
manually-advanced status. Safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0392-outward-clearing-presentment" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_outward_clearing_presentment"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_outward_clearing_presentment">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="depositing_account_type" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="depositing_account_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="drawer_bank_micr" type="VARCHAR(20)"/>
|
||||
<column name="drawer_ifsc" type="VARCHAR(15)"/>
|
||||
<column name="drawer_bank_name" type="VARCHAR(150)"/>
|
||||
<column name="cheque_number" type="VARCHAR(25)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="amount" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="payee_name" type="VARCHAR(150)"/>
|
||||
<column name="deposited_date" type="DATE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="instrument_date" type="DATE"/>
|
||||
<column name="status" type="VARCHAR(25)" defaultValue="CAPTURED">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="batch_reference" type="VARCHAR(100)"/>
|
||||
<column name="sent_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="dishonour_reason_code" type="VARCHAR(10)"/>
|
||||
<column name="office_id" type="BIGINT"/>
|
||||
<column name="settled_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="created_by" type="BIGINT"/>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="version" type="INTEGER" defaultValueNumeric="0"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Shared net-settlement and reconciliation tables for CTS + NACH (distinguished by clearing_type).
|
||||
m_clearing_settlement_batch nets a decisioned session's pass/return totals and, when posted, squares
|
||||
off the clearing suspense GL against the settlement (RTGS) GL. m_clearing_reconciliation records the
|
||||
day-end CBS-vs-clearing-house match. Every changeSet is a safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0393-clearing-settlement-batch" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_clearing_settlement_batch"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_clearing_settlement_batch">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="clearing_type" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="settlement_date" type="DATE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="direction" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="source_reference" type="VARCHAR(100)"/>
|
||||
<column name="source_batch_id" type="BIGINT"/>
|
||||
<column name="total_passed_amount" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="total_returned_amount" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="net_amount" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="passed_count" type="INTEGER" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="returned_count" type="INTEGER" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="office_id" type="BIGINT"/>
|
||||
<column name="currency_code" type="VARCHAR(3)"/>
|
||||
<column name="gl_transaction_id" type="VARCHAR(100)"/>
|
||||
<column name="status" type="VARCHAR(15)" defaultValue="PENDING">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="prepared_by" type="BIGINT"/>
|
||||
<column name="prepared_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="posted_by" type="BIGINT"/>
|
||||
<column name="posted_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="rejection_reason" type="VARCHAR(500)"/>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0393-clearing-reconciliation" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_clearing_reconciliation"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_clearing_reconciliation">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="clearing_type" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="reconciliation_date" type="DATE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="source_reference" type="VARCHAR(100)"/>
|
||||
<column name="cbs_total" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="clearing_house_total" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="difference" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="status" type="VARCHAR(15)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="detail" type="VARCHAR(1000)"/>
|
||||
<column name="run_by" type="BIGINT"/>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0393-clearing-settlement-gl-config-seed" author="CBS" runOnChange="false">
|
||||
<sql>
|
||||
INSERT INTO m_clearing_gl_config (config_key, description, gl_account_id)
|
||||
SELECT 'CLEARING_SETTLEMENT_RTGS', 'Net settlement / RTGS control account for clearing', NULL
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_gl_config WHERE config_key = 'CLEARING_SETTLEMENT_RTGS');
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
NACH (National Automated Clearing House): recurring, mandate-based bulk clearing (spec sections 7-8).
|
||||
- m_nach_mandate : a customer's signed authorization to debit/credit their account repeatedly
|
||||
- m_nach_batch : a sponsor bank's batch of due debits/credits for a cycle
|
||||
- m_nach_transaction : one debit/credit within a batch, with validation results + pass/return decision
|
||||
|
||||
Return details live on the transaction row (decision=RETURN + return_reason_code), mirroring the CTS
|
||||
inward-item design, rather than a separate returns table. Settlement + reconciliation reuse the shared
|
||||
m_clearing_settlement_batch / m_clearing_reconciliation tables (clearing_type='NACH'). Safe no-op where
|
||||
already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0394-nach-mandate" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_nach_mandate"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_nach_mandate">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="mandate_reference" type="VARCHAR(50)">
|
||||
<constraints nullable="false" unique="true" uniqueConstraintName="uk_nach_mandate_ref"/>
|
||||
</column>
|
||||
<column name="account_type" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="account_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="sponsor_bank_id" type="BIGINT">
|
||||
<constraints nullable="true" foreignKeyName="fk_nach_mandate_sponsor" references="m_clearing_bank(id)"/>
|
||||
</column>
|
||||
<column name="mandate_type" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="amount" type="DECIMAL(19,6)"/>
|
||||
<column name="max_amount" type="DECIMAL(19,6)"/>
|
||||
<column name="frequency" type="VARCHAR(15)"/>
|
||||
<column name="start_date" type="DATE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="end_date" type="DATE"/>
|
||||
<column name="debtor_name" type="VARCHAR(150)"/>
|
||||
<column name="purpose" type="VARCHAR(150)"/>
|
||||
<column name="status" type="VARCHAR(15)" defaultValue="ACTIVE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="cancelled_reason" type="VARCHAR(500)"/>
|
||||
<column name="cancelled_by" type="BIGINT"/>
|
||||
<column name="cancelled_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="created_by" type="BIGINT"/>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="version" type="INTEGER" defaultValueNumeric="0"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0394-nach-batch" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_nach_batch"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_nach_batch">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="batch_reference" type="VARCHAR(100)">
|
||||
<constraints nullable="false" unique="true" uniqueConstraintName="uk_nach_batch_ref"/>
|
||||
</column>
|
||||
<column name="sponsor_bank_id" type="BIGINT">
|
||||
<constraints nullable="true" foreignKeyName="fk_nach_batch_sponsor" references="m_clearing_bank(id)"/>
|
||||
</column>
|
||||
<column name="batch_type" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="value_date" type="DATE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="total_txn_count" type="INTEGER" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="total_amount" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="status" type="VARCHAR(15)" defaultValue="CREATED">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="office_id" type="BIGINT"/>
|
||||
<column name="created_by" type="BIGINT"/>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="processed_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="settled_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="version" type="INTEGER" defaultValueNumeric="0"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0394-nach-transaction" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_nach_transaction"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_nach_transaction">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="batch_id" type="BIGINT">
|
||||
<constraints nullable="false" foreignKeyName="fk_nach_txn_batch" references="m_nach_batch(id)"/>
|
||||
</column>
|
||||
<column name="mandate_id" type="BIGINT">
|
||||
<constraints nullable="true" foreignKeyName="fk_nach_txn_mandate" references="m_nach_mandate(id)"/>
|
||||
</column>
|
||||
<column name="account_type" type="VARCHAR(10)"/>
|
||||
<column name="account_id" type="BIGINT"/>
|
||||
<column name="txn_type" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="amount" type="DECIMAL(19,6)" defaultValueNumeric="0">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="mandate_active_check" type="BOOLEAN"/>
|
||||
<column name="amount_within_limit_check" type="BOOLEAN"/>
|
||||
<column name="balance_check_passed" type="BOOLEAN"/>
|
||||
<column name="account_check_passed" type="BOOLEAN"/>
|
||||
<column name="duplicate_check_passed" type="BOOLEAN"/>
|
||||
<column name="validation_detail" type="VARCHAR(1000)"/>
|
||||
<column name="decision" type="VARCHAR(10)" defaultValue="PENDING">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="return_reason_code" type="VARCHAR(10)"/>
|
||||
<column name="decision_reason" type="VARCHAR(500)"/>
|
||||
<column name="decisioned_by" type="BIGINT"/>
|
||||
<column name="decisioned_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="status" type="VARCHAR(15)" defaultValue="RECEIVED">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="settlement_batch_id" type="BIGINT"/>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="version" type="INTEGER" defaultValueNumeric="0"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Permissions for the CTS + NACH clearing modules. Every command that flows through Fineract's command
|
||||
pipeline needs a matching m_permission row (grouping 'portfolio', code '<ACTION>_<ENTITY>'). Only
|
||||
POST_CLEARINGSETTLEMENTBATCH is can_maker_checker=true (the one two-person-control point; a code-level
|
||||
self-poster guard backs it up because ALL_FUNCTIONS bypasses the flag in this tenant). MENU_CLEARING
|
||||
already exists (0231); MENU_CTSCLEARING / MENU_NACHCLEARING are added for optional finer nav gating.
|
||||
Idempotent via WHERE NOT EXISTS.
|
||||
-->
|
||||
|
||||
<changeSet id="0395-clearing-permissions" author="CBS" runOnChange="false">
|
||||
<sql>
|
||||
-- shared: clearing bank directory / keys
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_CLEARINGBANK', 'CLEARINGBANK', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_CLEARINGBANK');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'CREATE_CLEARINGBANK', 'CLEARINGBANK', 'CREATE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CREATE_CLEARINGBANK');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'BOOTSTRAP_CLEARINGBANK', 'CLEARINGBANK', 'BOOTSTRAP', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'BOOTSTRAP_CLEARINGBANK');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'ROTATEKEYS_CLEARINGBANK', 'CLEARINGBANK', 'ROTATEKEYS', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'ROTATEKEYS_CLEARINGBANK');
|
||||
|
||||
-- shared: return reason codes (read-only reference)
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_CLEARINGRETURNREASONCODE', 'CLEARINGRETURNREASONCODE', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_CLEARINGRETURNREASONCODE');
|
||||
|
||||
-- shared: settlement batch
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_CLEARINGSETTLEMENTBATCH', 'CLEARINGSETTLEMENTBATCH', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_CLEARINGSETTLEMENTBATCH');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'CREATE_CLEARINGSETTLEMENTBATCH', 'CLEARINGSETTLEMENTBATCH', 'CREATE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CREATE_CLEARINGSETTLEMENTBATCH');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'POST_CLEARINGSETTLEMENTBATCH', 'CLEARINGSETTLEMENTBATCH', 'POST', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'POST_CLEARINGSETTLEMENTBATCH');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'REJECT_CLEARINGSETTLEMENTBATCH', 'CLEARINGSETTLEMENTBATCH', 'REJECT', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'REJECT_CLEARINGSETTLEMENTBATCH');
|
||||
|
||||
-- shared: reconciliation
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_CLEARINGRECONCILIATION', 'CLEARINGRECONCILIATION', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_CLEARINGRECONCILIATION');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'CREATE_CLEARINGRECONCILIATION', 'CLEARINGRECONCILIATION', 'CREATE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CREATE_CLEARINGRECONCILIATION');
|
||||
|
||||
-- CTS inward batch
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_INWARDCLEARINGBATCH', 'INWARDCLEARINGBATCH', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_INWARDCLEARINGBATCH');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'CREATE_INWARDCLEARINGBATCH', 'INWARDCLEARINGBATCH', 'CREATE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CREATE_INWARDCLEARINGBATCH');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'VALIDATE_INWARDCLEARINGBATCH', 'INWARDCLEARINGBATCH', 'VALIDATE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'VALIDATE_INWARDCLEARINGBATCH');
|
||||
|
||||
-- CTS inward item decisioning
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_INWARDCLEARINGITEM', 'INWARDCLEARINGITEM', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_INWARDCLEARINGITEM');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'PASS_INWARDCLEARINGITEM', 'INWARDCLEARINGITEM', 'PASS', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'PASS_INWARDCLEARINGITEM');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'RETURN_INWARDCLEARINGITEM', 'INWARDCLEARINGITEM', 'RETURN', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'RETURN_INWARDCLEARINGITEM');
|
||||
|
||||
-- CTS outward presentment
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_OUTWARDCLEARINGPRESENTMENT', 'OUTWARDCLEARINGPRESENTMENT', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_OUTWARDCLEARINGPRESENTMENT');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'CREATE_OUTWARDCLEARINGPRESENTMENT', 'OUTWARDCLEARINGPRESENTMENT', 'CREATE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CREATE_OUTWARDCLEARINGPRESENTMENT');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'SEND_OUTWARDCLEARINGPRESENTMENT', 'OUTWARDCLEARINGPRESENTMENT', 'SEND', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'SEND_OUTWARDCLEARINGPRESENTMENT');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'SETTLE_OUTWARDCLEARINGPRESENTMENT', 'OUTWARDCLEARINGPRESENTMENT', 'SETTLE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'SETTLE_OUTWARDCLEARINGPRESENTMENT');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'DISHONOUR_OUTWARDCLEARINGPRESENTMENT', 'OUTWARDCLEARINGPRESENTMENT', 'DISHONOUR', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'DISHONOUR_OUTWARDCLEARINGPRESENTMENT');
|
||||
|
||||
-- NACH mandate
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_NACHMANDATE', 'NACHMANDATE', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_NACHMANDATE');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'CREATE_NACHMANDATE', 'NACHMANDATE', 'CREATE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CREATE_NACHMANDATE');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'CANCEL_NACHMANDATE', 'NACHMANDATE', 'CANCEL', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CANCEL_NACHMANDATE');
|
||||
|
||||
-- NACH batch
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_NACHBATCH', 'NACHBATCH', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_NACHBATCH');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'CREATE_NACHBATCH', 'NACHBATCH', 'CREATE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CREATE_NACHBATCH');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'PROCESS_NACHBATCH', 'NACHBATCH', 'PROCESS', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'PROCESS_NACHBATCH');
|
||||
|
||||
-- NACH transaction decisioning
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_NACHTRANSACTION', 'NACHTRANSACTION', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_NACHTRANSACTION');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'PASS_NACHTRANSACTION', 'NACHTRANSACTION', 'PASS', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'PASS_NACHTRANSACTION');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'RETURN_NACHTRANSACTION', 'NACHTRANSACTION', 'RETURN', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'RETURN_NACHTRANSACTION');
|
||||
|
||||
-- menus (MENU_CLEARING already seeded in 0231; add module-specific ones for optional finer gating)
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'heading_menu', 'MENU_CTSCLEARING', 'MENU', 'CTSCLEARING', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'MENU_CTSCLEARING');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'heading_menu', 'MENU_NACHCLEARING', 'MENU', 'NACHCLEARING', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'MENU_NACHCLEARING');
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Cheque image capture + Image Quality Assessment (IQA) for inward clearing items (spec section 5 &
|
||||
the cheque_images concept in section 11). Front/back image references travel with the presented
|
||||
cheque; iqa_status (PASS / FAIL / PENDING / NA) records the automated image-quality outcome. A FAIL
|
||||
surfaces in validation and lets the item be returned with reason code 11 (Image Quality Failure),
|
||||
which was already seeded in 0390. Additive columns only; safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0396-inward-item-image-iqa" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_inward_clearing_item"/>
|
||||
<not><columnExists tableName="m_inward_clearing_item" columnName="iqa_status"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_inward_clearing_item">
|
||||
<column name="front_image_ref" type="VARCHAR(300)"/>
|
||||
<column name="back_image_ref" type="VARCHAR(300)"/>
|
||||
<column name="iqa_status" type="VARCHAR(10)" defaultValue="NA">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="iqa_detail" type="VARCHAR(500)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Positive Pay System (PPS) — RBI-mandated (since 2021) for cheques at or above a high-value threshold
|
||||
(default INR 50,000). The drawer pre-registers the cheque's key details; inward clearing then matches a
|
||||
presented high-value cheque against an ACTIVE registration and returns it (reason code 13) when there is
|
||||
no registration or the details differ. Adds the registration table, a positive_pay_check result column on
|
||||
the inward item, the '13' reason code, and permissions. Idempotent / safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0397-positive-pay-registration" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_positive_pay_registration"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_positive_pay_registration">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="account_type" type="VARCHAR(10)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="account_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="cheque_number" type="VARCHAR(25)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="instrument_date" type="DATE"/>
|
||||
<column name="amount" type="DECIMAL(19,6)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="payee_name" type="VARCHAR(150)"/>
|
||||
<column name="channel" type="VARCHAR(20)" defaultValue="BRANCH"/>
|
||||
<column name="status" type="VARCHAR(15)" defaultValue="ACTIVE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="registered_by" type="BIGINT"/>
|
||||
<column name="registered_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="cancelled_reason" type="VARCHAR(500)"/>
|
||||
<column name="cancelled_by" type="BIGINT"/>
|
||||
<column name="cancelled_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="version" type="INTEGER" defaultValueNumeric="0"/>
|
||||
</createTable>
|
||||
<createIndex tableName="m_positive_pay_registration" indexName="idx_pps_account_cheque">
|
||||
<column name="account_id"/>
|
||||
<column name="cheque_number"/>
|
||||
</createIndex>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0397-inward-item-positive-pay-check" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_inward_clearing_item"/>
|
||||
<not><columnExists tableName="m_inward_clearing_item" columnName="positive_pay_check"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_inward_clearing_item">
|
||||
<column name="positive_pay_check" type="BOOLEAN"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0397-positive-pay-reason-code" author="CBS" runOnChange="false">
|
||||
<sql>
|
||||
INSERT INTO m_clearing_return_reason_code (code, description, category, applies_to, is_active)
|
||||
SELECT '13', 'Positive Pay Data Mismatch / Not Registered', 'INSTRUMENT', 'CTS', true
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_clearing_return_reason_code WHERE code = '13');
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0397-positive-pay-permissions" author="CBS" runOnChange="false">
|
||||
<sql>
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'READ_POSITIVEPAYREGISTRATION', 'POSITIVEPAYREGISTRATION', 'READ', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_POSITIVEPAYREGISTRATION');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'CREATE_POSITIVEPAYREGISTRATION', 'POSITIVEPAYREGISTRATION', 'CREATE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CREATE_POSITIVEPAYREGISTRATION');
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'CANCEL_POSITIVEPAYREGISTRATION', 'POSITIVEPAYREGISTRATION', 'CANCEL', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CANCEL_POSITIVEPAYREGISTRATION');
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
When an outward presentment is SENT, the collecting bank now genuinely bundles it into a file,
|
||||
encrypts it for NPCI and signs it, and NPCI (simulated) decrypts/verifies and re-encrypts it for the
|
||||
drawer bank. These columns store the resulting encrypted outward envelope, the destination (drawer)
|
||||
bank it was routed to, and whether NPCI's signature verified — so the real crypto flow is visible on
|
||||
each cheque. Additive; safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0398-outward-npci-envelope" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_outward_clearing_presentment"/>
|
||||
<not><columnExists tableName="m_outward_clearing_presentment" columnName="outward_envelope"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_outward_clearing_presentment">
|
||||
<column name="outward_envelope" type="TEXT"/>
|
||||
<column name="routed_to_bank" type="VARCHAR(150)"/>
|
||||
<column name="npci_signature_valid" type="BOOLEAN"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Stores the full, human-readable CTS outward file (batchHeader + instrument + batchFooter, in the NPCI
|
||||
CTS-2010 shape) generated when a cheque is sent. The encrypted form travels to NPCI (outward_envelope);
|
||||
this plaintext copy is kept for display/audit so the operator can see exactly what was sent. Additive;
|
||||
safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0399-outward-cts-file" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_outward_clearing_presentment"/>
|
||||
<not><columnExists tableName="m_outward_clearing_presentment" columnName="cts_file_json"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_outward_clearing_presentment">
|
||||
<column name="cts_file_json" type="TEXT"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Outward presentment: stop-payment flag and cheque image/IQA fields, captured at deposit time so the
|
||||
CTS outward file reflects what the operator actually entered instead of a hardcoded PASS/false.
|
||||
Additive; safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0400-outward-iqa-stoppayment" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_outward_clearing_presentment"/>
|
||||
<not><columnExists tableName="m_outward_clearing_presentment" columnName="stop_payment_flag"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_outward_clearing_presentment">
|
||||
<column name="stop_payment_flag" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="front_image_ref" type="VARCHAR(300)"/>
|
||||
<column name="back_image_ref" type="VARCHAR(300)"/>
|
||||
<column name="iqa_status" type="VARCHAR(10)" defaultValue="NA">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="iqa_detail" type="VARCHAR(500)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Fields identified as missing from the outward CTS file vs. the real CTS-2010 structure: the drawer's
|
||||
account number (on the drawee bank), the presenting office/branch (drives depositBranchCode), and an
|
||||
optional grid zone override (real CTS files vary this by region, e.g. WZ/Western Zone Grid - Mumbai).
|
||||
Additive; safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0401-outward-cts-missing-fields" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_outward_clearing_presentment"/>
|
||||
<not><columnExists tableName="m_outward_clearing_presentment" columnName="drawer_account_number"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_outward_clearing_presentment">
|
||||
<column name="drawer_account_number" type="VARCHAR(34)"/>
|
||||
<column name="grid_zone_code" type="VARCHAR(10)"/>
|
||||
<column name="grid_zone_name" type="VARCHAR(100)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Permission for the "send all pending outward cheques to NPCI as one batch" action — used by both the
|
||||
manual "Send Pending Batch" button and the (disabled by default) clearing-session scheduled job.
|
||||
Idempotent via WHERE NOT EXISTS.
|
||||
-->
|
||||
|
||||
<changeSet id="0402-outward-send-batch-permission" author="CBS" runOnChange="false">
|
||||
<sql>
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'SENDBATCH_OUTWARDCLEARINGPRESENTMENT', 'OUTWARDCLEARINGPRESENTMENT', 'SENDBATCH', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'SENDBATCH_OUTWARDCLEARINGPRESENTMENT');
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
"CTS Outward Clearing Batch Send" scheduled job — mirrors the NEFT Batch Process / Verification Token
|
||||
Cleanup job seeding convention (see 0309/0310). Cron "0 0 10-18/2 * * ?" fires at 10:00, 12:00,
|
||||
14:00, 16:00 and 18:00 daily (every 2 hours, 10am-6pm; cron_expression is VARCHAR(20), so the
|
||||
step-range form is used instead of an explicit hour list, which would exceed that length), bundling
|
||||
every CAPTURED outward presentment into one CTS file and sending it to NPCI — the exact same business
|
||||
logic the manual "Send Pending Batch to NPCI" button on the Outward Clearing screen already calls
|
||||
directly.
|
||||
|
||||
Seeded is_active=false (disabled) by request — an operator can enable it later from the standard
|
||||
Admin > System > Manage Jobs screen once ready to automate outward sends; until then, only the manual
|
||||
button runs it.
|
||||
-->
|
||||
|
||||
<changeSet author="CBS" id="0403_outward_clearing_batch_job">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="0">SELECT COUNT(*) FROM job WHERE name = 'CTS Outward Clearing Batch Send'</sqlCheck>
|
||||
</preConditions>
|
||||
<insert tableName="job">
|
||||
<column name="name" value="CTS Outward Clearing Batch Send"/>
|
||||
<column name="short_name" value="CTS_OUTB"/>
|
||||
<column name="display_name" value="CTS Outward Clearing Batch Send"/>
|
||||
<column name="cron_expression" value="0 0 10-18/2 * * ?"/>
|
||||
<column name="create_time" valueDate="${current_datetime}"/>
|
||||
<column name="task_priority" valueNumeric="5"/>
|
||||
<column name="group_name"/>
|
||||
<column name="previous_run_start_time"/>
|
||||
<column name="job_key" value="CTS Outward Clearing Batch SendDetail1 _ DEFAULT"/>
|
||||
<column name="initializing_errorlog"/>
|
||||
<column name="is_active" valueBoolean="false"/>
|
||||
<column name="currently_running" valueBoolean="false"/>
|
||||
<column name="updates_allowed" valueBoolean="true"/>
|
||||
<column name="scheduler_group" valueNumeric="0"/>
|
||||
<column name="is_misfired" valueBoolean="false"/>
|
||||
<column name="node_id" valueNumeric="1"/>
|
||||
<column name="is_mismatched_job" valueBoolean="true"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Real cheque image storage for inward items and outward presentments, using the same
|
||||
ContentStoreService (filesystem/S3) abstraction already used by the election-candidate-symbol upload
|
||||
in this fork — NOT a DB blob. Each column stores "mimeType|storagePath" (matching that same
|
||||
convention); the actual bytes live wherever ContentStoreService is configured to write them. This is
|
||||
separate from the existing front_image_ref/back_image_ref columns, which remain a free-text label a
|
||||
user can type without uploading a real file. Additive; safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0404-inward-item-image-store" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_inward_clearing_item"/>
|
||||
<not><columnExists tableName="m_inward_clearing_item" columnName="front_image_store"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_inward_clearing_item">
|
||||
<column name="front_image_store" type="VARCHAR(500)"/>
|
||||
<column name="back_image_store" type="VARCHAR(500)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0404-outward-presentment-image-store" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_outward_clearing_presentment"/>
|
||||
<not><columnExists tableName="m_outward_clearing_presentment" columnName="front_image_store"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_outward_clearing_presentment">
|
||||
<column name="front_image_store" type="VARCHAR(500)"/>
|
||||
<column name="back_image_store" type="VARCHAR(500)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Closes the "what does NPCI actually forward to the destination/drawee bank" gap: until now the outward
|
||||
send flow stopped at "NPCI decrypted + verified our batch" and never modelled NPCI's own re-split/re-sign/
|
||||
re-encrypt step towards each destination bank, and the inward receive flow accepted an opaque
|
||||
client-supplied "inwardEnvelope" string instead of genuinely building/signing/encrypting one. Both sides
|
||||
now produce a real inwardPackageHeader/instruments/inwardPackageFooter JSON, NPCI-signed and encrypted
|
||||
for the destination bank's key, mirroring the existing outward batchHeader/instruments/batchFooter file.
|
||||
-->
|
||||
|
||||
<changeSet id="0405-outward-npci-inward-package" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_outward_clearing_presentment"/>
|
||||
<not><columnExists tableName="m_outward_clearing_presentment" columnName="npci_inward_package_json"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_outward_clearing_presentment">
|
||||
<column name="npci_inward_package_json" type="TEXT"/>
|
||||
<column name="npci_inward_envelope" type="TEXT"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0405-inward-batch-npci-package" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_inward_clearing_batch"/>
|
||||
<not><columnExists tableName="m_inward_clearing_batch" columnName="npci_processing_reference"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_inward_clearing_batch">
|
||||
<column name="presenting_bank_code" type="VARCHAR(15)"/>
|
||||
<column name="presenting_bank_name" type="VARCHAR(150)"/>
|
||||
<column name="npci_processing_reference" type="VARCHAR(50)"/>
|
||||
<column name="inward_package_json" type="TEXT"/>
|
||||
<column name="npci_signature_valid" type="BOOLEAN"/>
|
||||
<column name="return_tat_deadline" type="DATE"/>
|
||||
<column name="acknowledgement_required" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="acknowledgement_deadline" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
<column name="acknowledged" type="BOOLEAN" defaultValueBoolean="false"/>
|
||||
<column name="acknowledged_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0405-inward-item-npci-package" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_inward_clearing_item"/>
|
||||
<not><columnExists tableName="m_inward_clearing_item" columnName="original_serial_number"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_inward_clearing_item">
|
||||
<column name="original_serial_number" type="VARCHAR(20)"/>
|
||||
<column name="presenting_branch_code" type="VARCHAR(20)"/>
|
||||
<column name="return_deadline" type="DATE"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0405-inward-acknowledge-permission" author="CBS" runOnChange="false">
|
||||
<sql>
|
||||
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
|
||||
SELECT 'portfolio', 'ACKNOWLEDGE_INWARDCLEARINGBATCH', 'INWARDCLEARINGBATCH', 'ACKNOWLEDGE', false
|
||||
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'ACKNOWLEDGE_INWARDCLEARINGBATCH');
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Dedicated audit trail for every encrypt/sign/decrypt/verify hop in the clearing network (Bank-to-NPCI,
|
||||
NPCI-to-Bank): which bank sent to which bank, which recipient key was targeted, whether the signature
|
||||
verified, and where the plaintext + encrypted envelope were physically written on disk (via the same
|
||||
ContentStoreService used for cheque images) — so every crypto operation is independently inspectable,
|
||||
not just visible transiently in the JSON columns on the outward/inward rows themselves.
|
||||
-->
|
||||
|
||||
<changeSet id="0406-clearing-crypto-audit" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_clearing_crypto_audit"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_clearing_crypto_audit">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="sender_role" type="VARCHAR(10)"><constraints nullable="false"/></column>
|
||||
<column name="sender_bank_id" type="BIGINT"/>
|
||||
<column name="sender_bank_name" type="VARCHAR(150)"/>
|
||||
<column name="recipient_role" type="VARCHAR(10)"><constraints nullable="false"/></column>
|
||||
<column name="recipient_bank_id" type="BIGINT"/>
|
||||
<column name="recipient_bank_name" type="VARCHAR(150)"/>
|
||||
<column name="recipient_key_id" type="VARCHAR(100)"/>
|
||||
<column name="session_id" type="VARCHAR(50)"/>
|
||||
<column name="envelope_type" type="VARCHAR(30)"/>
|
||||
<column name="related_entity_type" type="VARCHAR(30)"><constraints nullable="false"/></column>
|
||||
<column name="related_entity_id" type="BIGINT"/>
|
||||
<column name="signature_valid" type="BOOLEAN"/>
|
||||
<column name="plaintext_file_path" type="VARCHAR(500)"/>
|
||||
<column name="encrypted_file_path" type="VARCHAR(500)"/>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"><constraints nullable="false"/></column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Reverses the in-process NPCI/multi-bank crypto simulation added in 0390/0395/0398/0399/0405/0406.
|
||||
This CBS will talk to a genuinely separate NPCI/peer-bank service later (real network call, its own
|
||||
key custody); simulating every role in one process was demo-only scaffolding and is removed here.
|
||||
Real, non-crypto behaviour is kept: the outward CTS-2010 file (cts_file_json), the descriptive
|
||||
presenting-bank fields, and RBI T+1 return TAT tracking (return_tat_deadline / return_deadline).
|
||||
Cannot edit the already-applied 0390/0395/0398/0399/0405/0406 changesets, so this is a new,
|
||||
additive-but-reversing migration instead.
|
||||
-->
|
||||
|
||||
<!--
|
||||
NACH's m_nach_mandate/m_nach_batch have their own, unrelated "sponsor bank" concept (a plain Long
|
||||
sponsor_bank_id column, no JPA relation — see NachMandate.java/NachBatch.java) whose DB-level FK
|
||||
happened to point at m_clearing_bank. That NACH feature is out of scope here and stays untouched;
|
||||
only the FK constraints (which would otherwise block dropping m_clearing_bank) are removed.
|
||||
-->
|
||||
<changeSet id="0407-drop-nach-sponsor-bank-fks" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<foreignKeyConstraintExists foreignKeyTableName="m_nach_mandate" foreignKeyName="fk_nach_mandate_sponsor"/>
|
||||
</preConditions>
|
||||
<dropForeignKeyConstraint baseTableName="m_nach_mandate" constraintName="fk_nach_mandate_sponsor"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0407-drop-nach-batch-sponsor-bank-fk" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<foreignKeyConstraintExists foreignKeyTableName="m_nach_batch" foreignKeyName="fk_nach_batch_sponsor"/>
|
||||
</preConditions>
|
||||
<dropForeignKeyConstraint baseTableName="m_nach_batch" constraintName="fk_nach_batch_sponsor"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0407-drop-clearing-bank-table" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<tableExists tableName="m_clearing_bank"/>
|
||||
</preConditions>
|
||||
<dropTable tableName="m_clearing_bank"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0407-drop-clearing-crypto-audit-table" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<tableExists tableName="m_clearing_crypto_audit"/>
|
||||
</preConditions>
|
||||
<dropTable tableName="m_clearing_crypto_audit"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0407-drop-outward-crypto-columns" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_outward_clearing_presentment"/>
|
||||
<columnExists tableName="m_outward_clearing_presentment" columnName="outward_envelope"/>
|
||||
</and>
|
||||
</preConditions>
|
||||
<dropColumn tableName="m_outward_clearing_presentment">
|
||||
<column name="outward_envelope"/>
|
||||
<column name="routed_to_bank"/>
|
||||
<column name="npci_signature_valid"/>
|
||||
<column name="npci_inward_package_json"/>
|
||||
<column name="npci_inward_envelope"/>
|
||||
</dropColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0407-drop-inward-batch-crypto-columns" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_inward_clearing_batch"/>
|
||||
<columnExists tableName="m_inward_clearing_batch" columnName="inward_envelope"/>
|
||||
</and>
|
||||
</preConditions>
|
||||
<dropColumn tableName="m_inward_clearing_batch">
|
||||
<column name="inward_envelope"/>
|
||||
<column name="npci_processing_reference"/>
|
||||
<column name="inward_package_json"/>
|
||||
<column name="npci_signature_valid"/>
|
||||
<column name="acknowledgement_required"/>
|
||||
<column name="acknowledgement_deadline"/>
|
||||
<column name="acknowledged"/>
|
||||
<column name="acknowledged_on"/>
|
||||
</dropColumn>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="0407-remove-clearing-crypto-permissions" author="CBS" runOnChange="false">
|
||||
<sql>
|
||||
DELETE FROM m_permission WHERE code IN (
|
||||
'READ_CLEARINGBANK', 'CREATE_CLEARINGBANK', 'BOOTSTRAP_CLEARINGBANK', 'ROTATEKEYS_CLEARINGBANK',
|
||||
'ACKNOWLEDGE_INWARDCLEARINGBATCH'
|
||||
);
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
This CBS's own RSA key pair for talking to the real, separate NPCI clearing-house service (a genuine
|
||||
second process, not the deleted in-CBS simulation). Singleton row, generated once on first use.
|
||||
private_key_pem never leaves this process; only public_key_pem is ever sent to NPCI, via bank
|
||||
self-registration (POST /banks on the NPCI service).
|
||||
-->
|
||||
|
||||
<changeSet id="0408-clearing-own-identity" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_clearing_own_identity"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_clearing_own_identity">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="public_key_pem" type="TEXT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="private_key_pem" type="TEXT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="registered_with_npci" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Stores NPCI's real routing response (signatureValid, routedTo, unroutable) for each outward batch,
|
||||
from the actual, separate NPCI clearing-house service — for audit/display alongside the existing
|
||||
cts_file_json column. Additive; safe no-op where already applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0409-outward-npci-response" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_outward_clearing_presentment"/>
|
||||
<not><columnExists tableName="m_outward_clearing_presentment" columnName="npci_response_json"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_outward_clearing_presentment">
|
||||
<column name="npci_response_json" type="TEXT"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
One row per package the real, separate NPCI clearing-house service has pushed to this CBS's
|
||||
inward-callback endpoint (POST /api/v1/{tenant}/npci/inward-push) — decrypted with this bank's own
|
||||
private key, NPCI's signature verified against NPCI's public key, kept here for manual review.
|
||||
Deliberately does not auto-create an InwardClearingBatch; inward stays a manual, reviewed step.
|
||||
-->
|
||||
|
||||
<changeSet id="0410-npci-inward-push-log" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<not><tableExists tableName="m_npci_inward_push_log"/></not>
|
||||
</preConditions>
|
||||
<createTable tableName="m_npci_inward_push_log">
|
||||
<column name="id" type="BIGINT" autoIncrement="true">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="npci_package_id" type="BIGINT"/>
|
||||
<column name="source_bank_code" type="VARCHAR(20)"/>
|
||||
<column name="destination_bank_code" type="VARCHAR(20)"/>
|
||||
<column name="source_batch_reference" type="VARCHAR(100)"/>
|
||||
<column name="signature_valid" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="decrypted_package_json" type="TEXT"/>
|
||||
<column name="received_on" type="TIMESTAMP WITH TIME ZONE"/>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
A few descriptive fields carried on each CTS instrument from the depositing/sending side that were
|
||||
previously only preserved in the raw NPCI push audit log (m_npci_inward_push_log.decrypted_package_json)
|
||||
and not surfaced as their own columns/UI on the inward item itself. Additive; safe no-op where applied.
|
||||
-->
|
||||
|
||||
<changeSet id="0411-inward-item-source-details" author="CBS">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<and>
|
||||
<tableExists tableName="m_inward_clearing_item"/>
|
||||
<not><columnExists tableName="m_inward_clearing_item" columnName="cts_reference_number"/></not>
|
||||
</and>
|
||||
</preConditions>
|
||||
<addColumn tableName="m_inward_clearing_item">
|
||||
<column name="cts_reference_number" type="VARCHAR(50)"/>
|
||||
<column name="instrument_stop_payment_flag" type="BOOLEAN"/>
|
||||
<column name="deposit_date" type="DATE"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<!--
|
||||
Outward clearing is now a real session-batched flow (see the "Outward Clearing Batches" screen):
|
||||
cheques no longer send individually, they wait for the next 2-hourly clearing session. The
|
||||
"CTS Outward Clearing Batch Send" job (seeded inactive in 0403_outward_clearing_batch_job.xml) IS
|
||||
that 2-hourly session scheduler (cron "0 0 10-18/2 * * ?"), so it now needs to actually run.
|
||||
The manual "Send Pending Batch" button remains as a fallback if the scheduler has a problem.
|
||||
-->
|
||||
|
||||
<changeSet author="CBS" id="0412_activate_outward_clearing_batch_job">
|
||||
<preConditions onFail="MARK_RAN">
|
||||
<sqlCheck expectedResult="1">SELECT COUNT(*) FROM job WHERE name = 'CTS Outward Clearing Batch Send' AND is_active = false</sqlCheck>
|
||||
</preConditions>
|
||||
<update tableName="job">
|
||||
<column name="is_active" valueBoolean="true"/>
|
||||
<where>name = 'CTS Outward Clearing Batch Send'</where>
|
||||
</update>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
Reference in New Issue
Block a user