feat: Client & CKYC UI improvements — filters, KYC management, image crop+merge

- Clients list: CKYC icon, CKYC Number column, status/legal form/CKYC filters
- CKYC: SFTP upload logs, date formatting, modal z-index fix, non-dismissible dialogs
- KYC Management: new standalone module with alert dashboard, notification scheduler, audit inventory, account status
- Image cropper: ngx-image-cropper integration for front+back document merge into single PNG
- Sidebar: KYC Management menu entry after CKYC

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aditya
2026-04-16 13:51:11 +05:30
co-authored by Claude Opus 4.6
parent 79e455c4ed
commit d72e969dc3
210 changed files with 14273 additions and 1139 deletions
+97
View File
@@ -320,6 +320,80 @@ export class ClientsService {
return this.http.get(`/clients/${clientId}/identifiers`);
}
getKycProofTypes(type?: 'id' | 'address'): Observable<any> {
const options = type ? { params: new HttpParams().set('type', type) } : {};
return this.http.get(`/kyc/proof-types`, options);
}
/**
* Phase 1 – Record Master: fetch clients missing CKYC registration
* or artefacts. Backed by GET /ckyc/record-master.
*/
getCkycRecordMaster(filters: {
officeId?: number | string;
productId?: number | string;
fromDate?: string;
toDate?: string;
missing?: 'photo' | 'signature' | 'id' | 'address' | 'any';
limit?: number;
offset?: number;
} = {}): Observable<any> {
let params = new HttpParams();
Object.entries(filters).forEach(([key, value]) => {
if (value !== null && value !== undefined && value !== '') {
params = params.set(key, String(value));
}
});
return this.http.get(`/ckyc/record-master`, { params });
}
/**
* Phase 2 – Auto ZIP Creation: bundle selected clients into a CERSAI
* ZIP on the server. Backed by POST /ckyc/batches.
*/
createCkycBatch(body: { clientIds: (number | string)[]; remarks?: string }): Observable<any> {
return this.http.post(`/ckyc/batches`, body);
}
/**
* Phase 2/3 – List CKYC batches. Supports filters and an optional
* groupByDate=true to bucket results by created_on for the UI.
*/
getCkycBatches(filters: {
fromDate?: string;
toDate?: string;
uploadedToCersai?: boolean;
groupByDate?: boolean;
} = {}): Observable<any> {
let params = new HttpParams();
Object.entries(filters).forEach(([key, value]) => {
if (value !== null && value !== undefined && value !== '') {
params = params.set(key, String(value));
}
});
return this.http.get(`/ckyc/batches`, { params });
}
/** Fetch a single CKYC batch with parsed manifest. */
getCkycBatchById(id: number | string): Observable<any> {
return this.http.get(`/ckyc/batches/${id}`);
}
/** Download the ZIP attached to a batch (via generic document endpoint). */
downloadCkycBatchZip(parentEntityId: number | string, documentId: number | string): Observable<Blob> {
return this.http.get(`/ckyc_batch/${parentEntityId}/documents/${documentId}/attachment`, {
responseType: 'blob'
});
}
/**
* Phase 3 – SFTP upload to CERSAI. Uploads the batch ZIP over the
* SFTP channel and returns the ACK + per-client CKYC numbers.
*/
uploadCkycBatchToSftp(batchId: number | string): Observable<any> {
return this.http.post(`/ckyc/batches/${batchId}/sftp-upload`, {});
}
getClientIdentifierTemplate(clientId: string) {
return this.http.get(`/clients/${clientId}/identifiers/template`);
}
@@ -653,6 +727,29 @@ export class ClientsService {
return this.http.post(`/clients/${clientId}/kyc/${kycId}?command=verify-gstin`, {});
}
/**
* Verifies DIN (Director Identification Number) for an authorized signatory.
* Sends signatory clientId, DIN number and the non-individual entity name.
* Backend saves DIN & verification status in KYC table and returns company list.
* @param clientId Signatory's Client ID
* @param kycId KYC record ID
* @param dinNumber DIN number to verify
* @param entityName Non-individual entity name (for company match)
*/
verifyDIN(clientId: string, kycId: string, dinNumber: string, entityName: string): Observable<any> {
return this.http.post(`/clients/${clientId}/kyc/${kycId}?command=verify-din`, { dinNumber, entityName });
}
/**
* Completes Re-KYC after uploading signed self-declaration form.
* Updates Last Verified date to today and sets new Expiry Date (today + 10 years for low risk).
* @param clientId Client ID
* @param kycId KYC record ID
*/
completeReKyc(clientId: string, kycId: string): Observable<any> {
return this.http.post(`/clients/${clientId}/kyc/${kycId}?command=complete-rekyc`, {});
}
// ═══ Entity Classification APIs ═══
getEntityClassifications(clientId: string): Observable<any> {