Edit-mode now shows the previously selected KYC document type + uploaded file thumbnail
(loads from /clients/{id}/identifiers + /client_identifiers/{id}/documents). Same for
address proof on the India address step. Closes the gap where editing a client showed
an empty file picker even when proof had been uploaded on create.
Identifier-save hardened across all three callsites (create-client, edit-client,
identities-tab.createIdentifierWithDocs) - the KYC chip picker proofId is a CODE
string ('AADHAAR'), but backend ClientIdentifierRequest.documentTypeId is Long, which
Spring rejects with HttpMessageNotReadableException -> 400. resolveDocumentTypeId
helper looks up the code against /kyc/proof-types?type=id and substitutes the numeric
CodeValue id before posting. Skips silently for constitution-specific non-individual
docs that have no CodeValue mapping.
KYC payload normalises panNumber / enterprisePan / gstinNumber / cinNumber via
toUpperCase + whitespace strip so user-typed lowercase or trailing spaces don't trip
the backend regex (validation.msg.CLIENTKYC.panNumber.does.not.match.regexp).
State name match in client-address save now normalises both sides (lowercase, collapse
underscores + spaces) so legacy MADHYA_PRADESH resolves to 'Madhya Pradesh' returned
by api.postalpincode.in. Backed by tenant migration 0297.
Identities-tab resolver flattened - was returning identifiers before the per-row
forkJoin(getClientIdentificationDocuments) completed, so the view rendered empty
documents arrays. Now uses switchMap + forkJoin so the resolver awaits completion.
Also bundles concurrent work-in-progress on letter-mgmt, organization, users,
bank-calendar, shell, nominee/notes/identifier dialogs, and theming.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
73 lines
9.5 KiB
JSON
73 lines
9.5 KiB
JSON
{
|
|
"permissions": {
|
|
"allow": [
|
|
"Bash(npx ng build --configuration=development)",
|
|
"Bash(npx ng build)",
|
|
"Bash(curl -sk -X POST \"https://localhost:8443/fineract-provider/api/v1/clients/2/kyc\" -H \"Content-Type: application/json\" -H \"Fineract-Platform-TenantId: default\" -u \"mifos:password\" -d '{\"\"kycType\"\":1,\"\"riskCategory\"\":1,\"\"panNumber\"\":\"\"ABCDE1234F\"\",\"\"aadhaarNumberMasked\"\":\"\"XXXXXXXX1234\"\",\"\"remarks\"\":\"\"Test KYC\"\"}')",
|
|
"Bash(curl -sk -X POST \"https://localhost:8443/fineract-provider/api/v1/clients/2/kyc\" -H \"Content-Type: application/json\" -H \"Fineract-Platform-TenantId: default\" -u \"mifos:password\" -d '{\"\"kycType\"\":1,\"\"riskCategory\"\":1,\"\"panNumber\"\":\"\"ABCDE1234F\"\",\"\"aadhaarNumberMasked\"\":\"\"XXXXXXXX1234\"\",\"\"remarks\"\":\"\"Test KYC\"\",\"\"locale\"\":\"\"en\"\"}')",
|
|
"Bash(xargs grep -l \"ClientKycCommandFromApiJsonDeserializer\\\\|initiateClientKyc\")",
|
|
"Bash(npx ng build --configuration development)",
|
|
"Bash(xargs grep -l \"print\\\\|report\\\\|export\\\\|pdf\")",
|
|
"Bash(xargs grep -l \"export.*pdf\\\\|download.*pdf\\\\|print\")",
|
|
"Bash(xargs grep -l \"print\\\\|pdf\\\\|export\")",
|
|
"Bash(xargs grep -l -i \"nominee\\\\|nomination\\\\|nominate\")",
|
|
"Bash(git -C \"c:/Users/adity/Music/CBS/UI/web-app\" log --oneline --all -n 50)",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); console.log\\(''heading:'', !!j.labels?.heading?.[''Fund Details'']\\); console.log\\(''inputs:'', !!j.labels?.inputs?.[''Fund Details'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading[''Fund Details'']; const i=j.labels.inputs[''Fund Details'']; console.log\\(''heading:'', h\\); console.log\\(''inputs:'', i\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const keys=Object.keys\\(j.labels\\); for\\(const k of keys\\){if\\(j.labels[k][''Fund Details'']\\){console.log\\(''Found in:'',k\\)}}\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading; const keys=Object.keys\\(h\\).filter\\(k=>k.startsWith\\(''Fu''\\)\\); console.log\\(keys\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading; console.log\\(''Create Loan Originator:'', h[''Create Loan Originator'']\\); console.log\\(''Edit Loan Originator:'', h[''Edit Loan Originator'']\\); console.log\\(''Loan Originator Details:'', h[''Loan Originator Details'']\\); console.log\\(''Loan Originators:'', h[''Loan Originators'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading; console.log\\(''Create Fund:'', h[''Create Fund'']\\); console.log\\(''Edit Fund:'', h[''Edit Fund'']\\); console.log\\(''Manage Funds:'', h[''Manage Funds'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); console.log\\(''Edit Employee in heading:'', j.labels.heading[''Edit Employee'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); for\\(const k of Object.keys\\(j.labels\\)\\){if\\(j.labels[k][''Edit Employee'']\\){console.log\\(''Found in:'',k\\)}}\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading; const edits=Object.keys\\(h\\).filter\\(k=>k.startsWith\\(''Edit''\\)\\); console.log\\(edits\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading; console.log\\(''Create Fund:'', h[''Create Fund'']\\); console.log\\(''Edit Fund:'', h[''Edit Fund'']\\); console.log\\(''Fund Details:'', h[''Fund Details'']\\); console.log\\(''Create Loan Originator:'', h[''Create Loan Originator'']\\); console.log\\(''Edit Loan Originator:'', h[''Edit Loan Originator'']\\); console.log\\(''Loan Originator Details:'', h[''Loan Originator Details'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading; console.log\\(''Create Teller:'', h[''Create Teller'']\\); console.log\\(''Edit Teller:'', h[''Edit Teller'']\\); console.log\\(''Teller Details:'', h[''Teller Details'']\\); console.log\\(''Tellers:'', h[''Teller / Cashier Management'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); console.log\\(''Cashiers:'', j.labels.heading[''Cashiers'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading; console.log\\(''Create Cashier:'', h[''Create Cashier'']\\); console.log\\(''Edit Cashier:'', h[''Edit Cashier'']\\); console.log\\(''Cashier Details:'', h[''Cashier Details'']\\); console.log\\(''Cashier Assignment:'', h[''Cashier Assignment'']\\); console.log\\(''Schedule:'', h[''Schedule'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading; console.log\\(''Allocate Cash:'', h[''Allocate Cash'']\\); console.log\\(''Settle Cash:'', h[''Settle Cash'']\\); console.log\\(''Cash Transactions:'', h[''Cash Transactions'']\\); console.log\\(''Transaction Details:'', h[''Transaction Details'']\\); console.log\\(''Cashier Summary:'', h[''Cashier Summary'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading; console.log\\(''Create Payment Type:'', h[''Create Payment Type'']\\); console.log\\(''Edit Payment Type:'', h[''Edit Payment Type'']\\); console.log\\(''Payment Type Details:'', h[''Payment Type Details'']\\); console.log\\(''Payment Type:'', h[''Payment Type'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); console.log\\(''Products:'', j.labels.heading[''Products'']\\);\")",
|
|
"Bash(node -e \"const j=require\\(''./src/assets/translations/en-US.json''\\); const h=j.labels.heading; console.log\\(''Create Savings Product:'', h[''Create Savings Product'']\\); console.log\\(''Edit Savings Product:'', h[''Edit Savings Product'']\\);\")",
|
|
"Bash(grep -n '\"\"inputs\"\"' src/assets/translations/en-US.json)",
|
|
"Bash(for key:*)",
|
|
"Bash(do)",
|
|
"Bash(if grep:*)",
|
|
"Bash(then)",
|
|
"Bash(echo \"EXISTS: $key\")",
|
|
"Bash(node -e \":*)",
|
|
"Bash(npx ng:*)",
|
|
"Bash(npm start:*)",
|
|
"Bash(node -e \"const j = require\\(''./src/assets/translations/en-US.json''\\); console.log\\(''heading key:'', j.labels?.heading?.[''Create Recurring Deposit Product'']\\); console.log\\(''inputs key:'', j.labels?.inputs?.[''Create Recurring Deposit Product'']\\);\")",
|
|
"Bash(node -e \"const fs = require\\(''fs''\\); const t = fs.readFileSync\\(''./src/assets/translations/en-US.json'',''utf8''\\); const j = JSON.parse\\(t\\); const keys = Object.keys\\(j.labels?.heading || {}\\); console.log\\(''heading keys count:'', keys.length\\); console.log\\(''last 5 keys:'', keys.slice\\(-5\\)\\); const cKeys = keys.filter\\(k => k.startsWith\\(''Create''\\)\\); console.log\\(''Create keys:'', cKeys\\);\")",
|
|
"Bash(node -e \"const j = require\\(''./src/assets/translations/en-US.json''\\); console.log\\(''heading:'', j.labels?.heading?.[''Create Recurring Deposit Product'']\\); console.log\\(''inputs:'', j.labels?.inputs?.[''Create Recurring Deposit Product'']\\);\")",
|
|
"Bash(do node:*)",
|
|
"Bash(grep -n '\"\"Tax Group\"\":' src/assets/translations/en-US.json)",
|
|
"Bash(node -e \"console.log\\(require\\(''./src/assets/translations/en-US.json''\\).labels?.heading?.[''System'']\\)\")",
|
|
"Bash(npm list:*)",
|
|
"Bash(find c:UsersadityMusicCBS -type d -name *fineract*)",
|
|
"Bash(xargs -I {} basename {})",
|
|
"Bash(findstr /n \"faExchange faBolt faClock faPaperPlane faFlask faSpinner faUserFriends faCommentDots faListAlt faInfoCircle faSearch faTimes faUndo faCheckCircle faExclamationTriangle\" \"c:\\\\Users\\\\adity\\\\Music\\\\CBS\\\\UI\\\\web-app\\\\src\\\\app\\\\shared\\\\icons.module.ts\")",
|
|
"Bash(findstr /i \"error neft-rtgs digital\")",
|
|
"Bash(findstr /I /C:\"error\" /C:\"neft-rtgs\" /C:\"digital\")",
|
|
"Bash(findstr /V \"warning\")",
|
|
"Bash(dir \"C:\\\\Users\\\\adity\\\\Music\\\\CBS\\\\UI\\\\web-app\\\\src\\\\app\\\\settings\")",
|
|
"Bash(findstr \"merge_code_update\")",
|
|
"Bash(node -e \"console.log\\(JSON.stringify\\(require\\('./package.json'\\).prettier || 'no config'\\)\\)\")",
|
|
"Bash(node node_modules/prettier/bin/prettier.cjs --write --ignore-unknown \"src/**/*.{ts,html,scss,css}\")",
|
|
"Bash(node node_modules/prettier/bin/prettier.cjs --check --ignore-unknown \"src/**/*.{ts,html,scss,css}\")",
|
|
"Bash(Get-ChildItem -Path \"c:\\\\Users\\\\adity\\\\Music\\\\CBS\\\\UI\\\\web-app\\\\src\\\\app\\\\\" -Directory | Select-Object Name)",
|
|
"Bash(Get-ChildItem -Path \"c:\\\\Users\\\\adity\\\\Music\\\\CBS\\\\UI\\\\web-app\\\\src\\\\app\" -Directory)",
|
|
"Bash(Select-Object Name)",
|
|
"Bash(Get-ChildItem -Path \"c:\\\\Users\\\\adity\\\\Music\\\\CBS\\\\UI\\\\web-app\\\\src\\\\app\\\\loans\" -Recurse -File)",
|
|
"Bash(Select-Object FullName)",
|
|
"Bash(ConvertTo-Csv -NoTypeInformation)",
|
|
"Bash(Out-String)",
|
|
"Bash(node node_modules/prettier/bin/prettier.cjs --write \"src/**/*.{ts,html,scss}\")",
|
|
"Bash(node node_modules/stylelint/bin/stylelint.mjs --fix \"src/**/*.scss\")",
|
|
"Bash(node node_modules/stylelint/bin/stylelint.mjs \"src/**/*.scss\")",
|
|
"Bash(node node_modules/eslint/bin/eslint.js --cache \"src/app/users/users.component.ts\")"
|
|
]
|
|
}
|
|
}
|