From 58187c23d0b8ce5d4b476907dbed6cced34a9877 Mon Sep 17 00:00:00 2001 From: Nitesh Yadav Date: Thu, 27 Aug 2026 11:26:00 +0530 Subject: [PATCH] fix(migrations): remove fake test-data seeds, backfill lost permissions, merge redundant roles Migration-hygiene fixes found while auditing whether a fresh database would end up with the same schema/permissions/roles as this dev database. 1. Remove fake test-data seed migrations 0449_seed_aml_test_alerts.xml and 0459_seed_aml_alerts_awaiting_review.xml unconditionally inserted 3 fictional clients (CLIENT_RAJESH/SONIA/VIKRAM) and 5 fake AML alerts against them on every environment, including production if this migration path ever ran there. 0459's own comment confirms it was written purely to exercise the AML review UI. Deleted both files and their entries; cleaned the same fake rows out of this dev database (3 clients, 5 alerts, plus the now-orphaned databasechangelog bookkeeping rows for the two deleted files). 2. Backfill 3 permissions lost to a migration-number collision Auditing all 2712 changesets applied to this dev database against the current codebase found 18 changeset filenames with no matching file anywhere in git; changelog-tenant.xml itself already documents the root cause (multiple branches independently reusing the same numeric prefix for unrelated migrations, e.g. 0456-0462 twice). Cross-checking each affected table/permission against actual Java usage (@CommandType handlers, domain/API classes, and both permission-insert styles used in this codebase -- Liquibase columns and raw literals) showed 15 of the 18 are genuinely dead (reconciliation-batch/settlement- cycle prototype tables, fixed asset/inventory tracking) with zero current code referencing them, so nothing to backfill there. The remaining 3 -- MENU_RECONCILIATION, READ_RECONCILIATION, SIDEBAR_RECONCILIATION -- gate a live module (CashReconciliation / ClearingReconciliation have real API resources and domain classes) but were never seeded by any migration; without them a fresh database can build and expose the reconciliation screens with no way to grant a role access to them. Added 0491_add_reconciliation_menu_permissions.xml. 3. Merge two pairs of redundant roles - "Bank Cashier" (4 fund-transfer permissions, 0 of which overlapped "CASHIER", 0 users assigned) folded into CASHIER. - "AML Officer" (2 permissions, both already present on "Principal Officer", 0 users assigned) folded into Principal Officer. Both migrations copy any missing permissions and move any assigned users onto the surviving role before deleting the redundant one, so they're safe to run against an environment that isn't empty the way this dev database is. Applied the same merge directly to this dev database's m_role / m_role_permission / m_appuser_role rows. Co-Authored-By: Claude Sonnet 5 --- .../db/changelog/tenant/changelog-tenant.xml | 5 +- .../parts/0449_seed_aml_test_alerts.xml | 108 ------------------ .../0459_seed_aml_alerts_awaiting_review.xml | 72 ------------ ...94_add_reconciliation_menu_permissions.xml | 62 ++++++++++ ...5_merge_bank_cashier_role_into_cashier.xml | 81 +++++++++++++ ...ml_officer_role_into_principal_officer.xml | 64 +++++++++++ 6 files changed, 210 insertions(+), 182 deletions(-) delete mode 100644 fineract-provider/src/main/resources/db/changelog/tenant/parts/0449_seed_aml_test_alerts.xml delete mode 100644 fineract-provider/src/main/resources/db/changelog/tenant/parts/0459_seed_aml_alerts_awaiting_review.xml create mode 100644 fineract-provider/src/main/resources/db/changelog/tenant/parts/0494_add_reconciliation_menu_permissions.xml create mode 100644 fineract-provider/src/main/resources/db/changelog/tenant/parts/0495_merge_bank_cashier_role_into_cashier.xml create mode 100644 fineract-provider/src/main/resources/db/changelog/tenant/parts/0496_merge_aml_officer_role_into_principal_officer.xml diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml index 2c023d719..3e40835df 100644 --- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml +++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml @@ -501,7 +501,6 @@ - @@ -523,7 +522,6 @@ - @@ -570,4 +568,7 @@ + + + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0449_seed_aml_test_alerts.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0449_seed_aml_test_alerts.xml deleted file mode 100644 index 5749f87d9..000000000 --- a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0449_seed_aml_test_alerts.xml +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - SELECT COUNT(*) FROM m_client WHERE external_id = 'CLIENT_RAJESH' - - - INSERT INTO m_client ( - account_no, external_id, status_enum, office_id, display_name, - fullname, is_staff, activation_date, office_joining_date, - submittedon_date, legal_form_enum, - created_on_utc, created_by, - last_modified_on_utc, last_modified_by, - cif_number - ) - VALUES - ( - 'ACC0000002', 'CLIENT_RAJESH', 300, 1, 'Rajesh Kumar', - 'Rajesh Kumar', false, CURRENT_DATE, CURRENT_DATE, - CURRENT_DATE, 1, - NOW(), 1, - NOW(), 1, - 'CIF_RAJESH' - ), - ( - 'ACC0000003', 'CLIENT_SONIA', 300, 1, 'Sonia Sharma', - 'Sonia Sharma', false, CURRENT_DATE, CURRENT_DATE, - CURRENT_DATE, 1, - NOW(), 1, - NOW(), 1, - 'CIF_SONIA' - ), - ( - 'ACC0000004', 'CLIENT_VIKRAM', 300, 1, 'Vikram Malhotra', - 'Vikram Malhotra', false, CURRENT_DATE, CURRENT_DATE, - CURRENT_DATE, 1, - NOW(), 1, - NOW(), 1, - 'CIF_VIKRAM' - ); - - - - - - - SELECT COUNT(*) FROM m_aml_alert a - JOIN m_client c ON a.client_id = c.id - WHERE c.external_id IN ('CLIENT_RAJESH', 'CLIENT_SONIA', 'CLIENT_VIKRAM') - - - - INSERT INTO m_aml_alert ( - transaction_type, transaction_id, client_id, rule_id, amount, currency_code, - raised_on, status, created_by, created_on_utc, last_modified_by, last_modified_on_utc, version - ) - VALUES - ( - 'SAVINGS', 1001, - (SELECT id FROM m_client WHERE external_id = 'CLIENT_RAJESH'), - (SELECT id FROM m_aml_transaction_rule WHERE rule_code = 'LARGE_CASH_TXN_25L'), - 3500000.000000, 'INR', - NOW(), 'RAISED', - 1, NOW(), 1, NOW(), 0 - ), - ( - 'SAVINGS', 1002, - (SELECT id FROM m_client WHERE external_id = 'CLIENT_SONIA'), - (SELECT id FROM m_aml_transaction_rule WHERE rule_code = 'STRUCTURING_BELOW_10L'), - 995000.000000, 'INR', - NOW(), 'RAISED', - 1, NOW(), 1, NOW(), 0 - ), - ( - 'SAVINGS', 1003, - (SELECT id FROM m_client WHERE external_id = 'CLIENT_VIKRAM'), - (SELECT id FROM m_aml_transaction_rule WHERE rule_code = 'PEP_ACCOUNT_MONITORING'), - 75000.000000, 'INR', - NOW(), 'RAISED', - 1, NOW(), 1, NOW(), 0 - ); - - - - diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0459_seed_aml_alerts_awaiting_review.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0459_seed_aml_alerts_awaiting_review.xml deleted file mode 100644 index eb2a6b00b..000000000 --- a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0459_seed_aml_alerts_awaiting_review.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - SELECT COUNT(*) FROM m_aml_alert WHERE transaction_id IN (2001, 2002) - - SELECT COUNT(*) FROM m_client WHERE external_id IN ('CLIENT_RAJESH', 'CLIENT_SONIA') - - - SELECT COUNT(*) FROM m_aml_transaction_rule - WHERE rule_code IN ('LARGE_CASH_TXN_25L', 'STRUCTURING_BELOW_10L') - - - - INSERT INTO m_aml_alert ( - transaction_type, transaction_id, client_id, rule_id, amount, currency_code, - raised_on, status, created_by, created_on_utc, last_modified_by, last_modified_on_utc, version - ) - VALUES - ( - 'SAVINGS', 2001, - (SELECT id FROM m_client WHERE external_id = 'CLIENT_RAJESH'), - (SELECT id FROM m_aml_transaction_rule WHERE rule_code = 'LARGE_CASH_TXN_25L'), - 4200000.000000, 'INR', - NOW(), 'RAISED', - 1, NOW(), 1, NOW(), 0 - ), - ( - 'SAVINGS', 2002, - (SELECT id FROM m_client WHERE external_id = 'CLIENT_SONIA'), - (SELECT id FROM m_aml_transaction_rule WHERE rule_code = 'STRUCTURING_BELOW_10L'), - 980000.000000, 'INR', - NOW(), 'RAISED', - 1, NOW(), 1, NOW(), 0 - ); - - - - diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0494_add_reconciliation_menu_permissions.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0494_add_reconciliation_menu_permissions.xml new file mode 100644 index 000000000..6334e2a43 --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0494_add_reconciliation_menu_permissions.xml @@ -0,0 +1,62 @@ + + + + + + + + SELECT COUNT(*) FROM m_permission WHERE code = 'MENU_RECONCILIATION' + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0495_merge_bank_cashier_role_into_cashier.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0495_merge_bank_cashier_role_into_cashier.xml new file mode 100644 index 000000000..9a191c03a --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0495_merge_bank_cashier_role_into_cashier.xml @@ -0,0 +1,81 @@ + + + + + + + + + SELECT COUNT(*) FROM m_role WHERE name = 'Bank Cashier' + SELECT COUNT(*) FROM m_role WHERE name = 'CASHIER' + + + INSERT INTO m_role_permission (role_id, permission_id) + SELECT (SELECT id FROM m_role WHERE name = 'CASHIER'), bc_rp.permission_id + FROM m_role_permission bc_rp + WHERE bc_rp.role_id = (SELECT id FROM m_role WHERE name = 'Bank Cashier') + AND bc_rp.permission_id NOT IN ( + SELECT permission_id FROM m_role_permission + WHERE role_id = (SELECT id FROM m_role WHERE name = 'CASHIER') + ); + + + + + + SELECT COUNT(*) FROM m_role WHERE name = 'Bank Cashier' + SELECT COUNT(*) FROM m_role WHERE name = 'CASHIER' + + + INSERT INTO m_appuser_role (appuser_id, role_id) + SELECT bc_ur.appuser_id, (SELECT id FROM m_role WHERE name = 'CASHIER') + FROM m_appuser_role bc_ur + WHERE bc_ur.role_id = (SELECT id FROM m_role WHERE name = 'Bank Cashier') + AND bc_ur.appuser_id NOT IN ( + SELECT appuser_id FROM m_appuser_role + WHERE role_id = (SELECT id FROM m_role WHERE name = 'CASHIER') + ); + + DELETE FROM m_appuser_role + WHERE role_id = (SELECT id FROM m_role WHERE name = 'Bank Cashier'); + + + + + + SELECT COUNT(*) FROM m_role WHERE name = 'Bank Cashier' + + + DELETE FROM m_role_permission WHERE role_id = (SELECT id FROM m_role WHERE name = 'Bank Cashier'); + DELETE FROM m_role WHERE name = 'Bank Cashier'; + + + + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0496_merge_aml_officer_role_into_principal_officer.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0496_merge_aml_officer_role_into_principal_officer.xml new file mode 100644 index 000000000..31d7ed93a --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0496_merge_aml_officer_role_into_principal_officer.xml @@ -0,0 +1,64 @@ + + + + + + + + + SELECT COUNT(*) FROM m_role WHERE name = 'AML Officer' + SELECT COUNT(*) FROM m_role WHERE name = 'Principal Officer' + + + INSERT INTO m_appuser_role (appuser_id, role_id) + SELECT ao_ur.appuser_id, (SELECT id FROM m_role WHERE name = 'Principal Officer') + FROM m_appuser_role ao_ur + WHERE ao_ur.role_id = (SELECT id FROM m_role WHERE name = 'AML Officer') + AND ao_ur.appuser_id NOT IN ( + SELECT appuser_id FROM m_appuser_role + WHERE role_id = (SELECT id FROM m_role WHERE name = 'Principal Officer') + ); + + DELETE FROM m_appuser_role + WHERE role_id = (SELECT id FROM m_role WHERE name = 'AML Officer'); + + + + + + SELECT COUNT(*) FROM m_role WHERE name = 'AML Officer' + + + DELETE FROM m_role_permission WHERE role_id = (SELECT id FROM m_role WHERE name = 'AML Officer'); + DELETE FROM m_role WHERE name = 'AML Officer'; + + + +