Add all CBS custom modules: KYC, Sanctions, RBI Feed, OpenProject, Mobile Lookup, Charges, Avro schemas

Includes all prior work not yet committed on this branch:
- KYC module (LincPay eKYC: PAN, Aadhaar OTP, GSTIN verification)
- Sanctions screening (UN Security Council consolidated list)
- RBI Feed integration with scheduled jobs
- OpenProject API integration
- Mobile lookup service
- Charge module enhancements (current account support)
- Client family member nominee fields
- Avro schema updates
- Liquibase migrations 0216-0224
- Postman collections for OpenProject, RBI Feeds, Sanctions
- SQL seed scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-03-18 17:54:10 +05:30
co-authored by Claude Opus 4.6
parent 78f37257a7
commit ba5365d4af
102 changed files with 9757 additions and 18 deletions
+155
View File
@@ -0,0 +1,155 @@
-- =============================================================================
-- KYC Module – Table Creation Script (PostgreSQL)
-- =============================================================================
-- DB Connection (from config/docker/env/postgresql.env & application.properties):
-- Host : localhost
-- Port : 5432
-- Database : fineract_default ← tenant database (your actual data lives here)
-- Username : postgres
-- Password : skdcnwauicn2ucnaecasdsajdnizucawencascdca
--
-- Run command:
-- psql -h localhost -p 5432 -U postgres -d fineract_default -f create_kyc_tables_postgresql.sql
--
-- (It will prompt for password: skdcnwauicn2ucnaecasdsajdnizucawencascdca)
-- =============================================================================
\connect fineract_default;
-- =============================================================================
-- TABLE: m_client_kyc
-- One KYC record per client (enforced by UNIQUE on client_id).
-- =============================================================================
CREATE TABLE IF NOT EXISTS m_client_kyc (
id BIGSERIAL NOT NULL,
client_id BIGINT NOT NULL,
-- kyc_status : 100=PENDING | 200=IN_PROGRESS | 300=VERIFIED | 400=REJECTED | 500=EXPIRED
kyc_status SMALLINT NOT NULL DEFAULT 100,
-- kyc_type : 1=INDIVIDUAL | 2=NON_INDIVIDUAL
kyc_type SMALLINT NOT NULL,
-- risk_category : 1=LOW (re-KYC 10yr) | 2=MEDIUM (8yr) | 3=HIGH (2yr)
risk_category SMALLINT NOT NULL DEFAULT 1,
-- PAN (Permanent Account Number – Income Tax Dept)
-- Format: 5 uppercase letters + 4 digits + 1 uppercase letter e.g. ABCDE1234F
pan_number VARCHAR(10),
pan_verified BOOLEAN NOT NULL DEFAULT FALSE,
pan_verified_on DATE,
-- Aadhaar – ONLY masked form stored (last 4 digits visible) per UIDAI directive
aadhaar_number_masked VARCHAR(12),
aadhaar_verified BOOLEAN NOT NULL DEFAULT FALSE,
aadhaar_verified_on DATE,
-- GSTIN (15-char GST Identification Number – mandatory for NON_INDIVIDUAL)
gstin_number VARCHAR(15),
gstin_verified BOOLEAN NOT NULL DEFAULT FALSE,
gstin_verified_on DATE,
-- CKYCRR – Central KYC Records Registry number (issued by CERSAI, 14 digits)
ckyc_number VARCHAR(14),
-- Lifecycle timestamps
initiated_on DATE,
verified_on DATE,
rejected_on DATE,
expiry_date DATE,
remarks VARCHAR(500),
-- Audit fields (AbstractAuditableWithUTCDateTimeCustom)
created_by BIGINT NOT NULL,
created_on_utc TIMESTAMP WITH TIME ZONE NOT NULL,
last_modified_by BIGINT NOT NULL,
last_modified_on_utc TIMESTAMP WITH TIME ZONE NOT NULL,
version BIGINT NOT NULL DEFAULT 0,
CONSTRAINT pk_m_client_kyc PRIMARY KEY (id),
CONSTRAINT uq_m_client_kyc_client_id UNIQUE (client_id),
CONSTRAINT fk_m_client_kyc_client_id
FOREIGN KEY (client_id) REFERENCES m_client(id)
ON DELETE RESTRICT ON UPDATE RESTRICT
);
COMMENT ON TABLE m_client_kyc IS 'RBI-mandated KYC record – one per client';
COMMENT ON COLUMN m_client_kyc.kyc_status IS '100=PENDING,200=IN_PROGRESS,300=VERIFIED,400=REJECTED,500=EXPIRED';
COMMENT ON COLUMN m_client_kyc.kyc_type IS '1=INDIVIDUAL, 2=NON_INDIVIDUAL';
COMMENT ON COLUMN m_client_kyc.risk_category IS '1=LOW(10yr), 2=MEDIUM(8yr), 3=HIGH(2yr) re-KYC period';
COMMENT ON COLUMN m_client_kyc.aadhaar_number_masked IS 'Masked Aadhaar: first 8 digits X, last 4 visible. Full number must NOT be stored per UIDAI directive.';
-- =============================================================================
-- TABLE: m_client_kyc_verification_log
-- Immutable audit trail for every 3rd-party API call.
-- =============================================================================
CREATE TABLE IF NOT EXISTS m_client_kyc_verification_log (
id BIGSERIAL NOT NULL,
kyc_id BIGINT NOT NULL,
-- verification_type: PAN | AADHAAR | GSTIN
verification_type VARCHAR(20) NOT NULL,
-- verification_status: SUCCESS | FAILURE | PENDING | ERROR
verification_status VARCHAR(20) NOT NULL,
request_reference VARCHAR(100),
api_response TEXT,
remarks VARCHAR(500),
-- Audit fields
created_by BIGINT NOT NULL,
created_on_utc TIMESTAMP WITH TIME ZONE NOT NULL,
last_modified_by BIGINT NOT NULL,
last_modified_on_utc TIMESTAMP WITH TIME ZONE NOT NULL,
version BIGINT NOT NULL DEFAULT 0,
CONSTRAINT pk_m_client_kyc_verification_log PRIMARY KEY (id),
CONSTRAINT fk_m_kyc_verification_log_kyc_id
FOREIGN KEY (kyc_id) REFERENCES m_client_kyc(id)
ON DELETE CASCADE ON UPDATE RESTRICT
);
COMMENT ON TABLE m_client_kyc_verification_log IS 'Audit log of all 3rd-party KYC API calls (PAN/Aadhaar/GSTIN)';
-- =============================================================================
-- PERMISSIONS
-- =============================================================================
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
SELECT 'portfolio', 'READ_CLIENTKYC', 'CLIENTKYC', 'READ', FALSE
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'READ_CLIENTKYC');
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
SELECT 'portfolio', 'CREATE_CLIENTKYC', 'CLIENTKYC', 'CREATE', TRUE
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'CREATE_CLIENTKYC');
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
SELECT 'portfolio', 'UPDATE_CLIENTKYC', 'CLIENTKYC', 'UPDATE', TRUE
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'UPDATE_CLIENTKYC');
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
SELECT 'portfolio', 'VERIFY_CLIENTKYC', 'CLIENTKYC', 'VERIFY', TRUE
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'VERIFY_CLIENTKYC');
INSERT INTO m_permission (grouping, code, entity_name, action_name, can_maker_checker)
SELECT 'portfolio', 'REJECT_CLIENTKYC', 'CLIENTKYC', 'REJECT', TRUE
WHERE NOT EXISTS (SELECT 1 FROM m_permission WHERE code = 'REJECT_CLIENTKYC');
-- =============================================================================
-- VERIFY CREATION
-- =============================================================================
SELECT tablename AS "Tables created"
FROM pg_tables
WHERE schemaname = 'public'
AND tablename LIKE 'm_client_kyc%';
SELECT code, entity_name, action_name
FROM m_permission
WHERE entity_name = 'CLIENTKYC';