@@ -35,6 +35,7 @@ import { JwtUtil } from '@utils/jwt-token';
35
35
import { ConfigService } from '@nestjs/config' ;
36
36
import { formatTime } from '@utils/formatTimeConversion' ;
37
37
import { API_RESPONSES } from '@utils/response.messages' ;
38
+ import { parse } from 'csv-parse/sync' ;
38
39
39
40
40
41
@Injectable ( )
@@ -952,6 +953,137 @@ export class PostgresUserService implements IServicelocator {
952
953
return APIResponse . error ( response , apiId , "Internal Server Error" , errorMessage , HttpStatus . INTERNAL_SERVER_ERROR ) ;
953
954
}
954
955
}
956
+ async bulkCreateUser ( request : any , userCreateDto : UserCreateDto , response : Response ) {
957
+ // check and validate all fields
958
+ let validatedRoles = await this . validateRequestBody ( userCreateDto )
959
+
960
+ if (
961
+ validatedRoles &&
962
+ Array . isArray ( validatedRoles ) &&
963
+ validatedRoles . length > 0
964
+ ) {
965
+ const errorMessage = validatedRoles . join ( "; " ) ;
966
+ throw new Error ( errorMessage ) ;
967
+ } else if ( validatedRoles ) {
968
+ throw new Error ( "Validation Error" ) ;
969
+ }
970
+
971
+ userCreateDto . username = userCreateDto . username . toLocaleLowerCase ( ) ;
972
+ const userSchema = new UserCreateDto ( userCreateDto ) ;
973
+
974
+ let errKeycloak = "" ;
975
+ let resKeycloak = "" ;
976
+
977
+ const keycloakResponse = await getKeycloakAdminToken ( ) ;
978
+ const token = keycloakResponse . data . access_token ;
979
+ let checkUserinKeyCloakandDb = await this . checkUserinKeyCloakandDb ( userCreateDto )
980
+ // let checkUserinDb = await this.checkUserinKeyCloakandDb(userCreateDto.username);
981
+ if ( checkUserinKeyCloakandDb ) {
982
+ throw new Error ( 'User Already Exist' )
983
+ }
984
+ resKeycloak = await createUserInKeyCloak ( userSchema , token ) . catch (
985
+ ( error ) => {
986
+ errKeycloak = error . response ?. data . errorMessage ;
987
+ throw new Error ( errKeycloak ) ;
988
+ }
989
+ ) ;
990
+
991
+ userCreateDto . userId = resKeycloak ;
992
+
993
+ let result = await this . createUserInDatabase ( request , userCreateDto , response ) ;
994
+ }
995
+
996
+ async bulkUploadUsers ( request : any , csvFile :any , response : Response ) {
997
+ const apiId = APIID . USER_CREATE_BULK ;
998
+ const decoded : any = jwt_decode ( request . headers . authorization ) ;
999
+
1000
+ try {
1001
+ if ( csvFile == undefined ) {
1002
+ return APIResponse . error (
1003
+ response ,
1004
+ apiId ,
1005
+ "BAD_REQUEST" ,
1006
+ "CSV file is required" ,
1007
+ HttpStatus . BAD_REQUEST
1008
+ ) ;
1009
+ }
1010
+ const csvData = csvFile . buffer . toString ( 'utf8' ) ;
1011
+
1012
+ // Parse CSV data
1013
+ const records = parse ( csvData , {
1014
+ columns : true ,
1015
+ skip_empty_lines : true ,
1016
+ trim : true
1017
+ } ) ;
1018
+
1019
+ const results = {
1020
+ success : 0 ,
1021
+ failed : 0 ,
1022
+ failedDetails : [ ]
1023
+ } ;
1024
+
1025
+ // Process each user record
1026
+ for ( const record of records ) {
1027
+ // Validate required fields
1028
+ if ( ! record . username || ! record . name || ! record . password ) {
1029
+ results . failed ++ ;
1030
+ results . failedDetails . push ( {
1031
+ record : record . username || 'Unknown' ,
1032
+ error : 'Missing required fields (username, name, or password)'
1033
+ } ) ;
1034
+ continue ;
1035
+ }
1036
+
1037
+ // Create UserCreateDto from CSV record
1038
+ let userCreateDto =
1039
+ {
1040
+ username :record . username . toLocaleLowerCase ( ) ,
1041
+ name : record . name ,
1042
+ password : record . password ,
1043
+ createdBy : decoded . sub ,
1044
+ updatedBy : decoded . sub ,
1045
+ tenantCohortRoleMapping : [
1046
+ {
1047
+ roleId : request . body . roleId ,
1048
+ tenantId : request . body . tenantId ,
1049
+ cohortId : [ request . body . cohortId ]
1050
+ }
1051
+ ]
1052
+ }
1053
+ const userSchema = new UserCreateDto ( userCreateDto ) ;
1054
+ try {
1055
+ await this . bulkCreateUser ( request , userSchema , response ) ;
1056
+ results . success ++ ;
1057
+ }
1058
+ catch ( error ) {
1059
+ results . failed ++ ;
1060
+ results . failedDetails . push ( {
1061
+ record : record . username || 'Unknown' ,
1062
+ error : error . message
1063
+ } ) ;
1064
+ }
1065
+ }
1066
+
1067
+ // Return overall results
1068
+ return APIResponse . success (
1069
+ response ,
1070
+ apiId ,
1071
+ results ,
1072
+ HttpStatus . OK ,
1073
+ `Bulk upload completed. Success: ${ results . success } , Failed: ${ results . failed } `
1074
+ ) ;
1075
+
1076
+ } catch ( e ) {
1077
+ const errorMessage = e . message || 'Internal server error' ;
1078
+ return APIResponse . error (
1079
+ response ,
1080
+ apiId ,
1081
+ "Internal Server Error" ,
1082
+ errorMessage ,
1083
+ HttpStatus . INTERNAL_SERVER_ERROR
1084
+ ) ;
1085
+ }
1086
+ }
955
1087
956
1088
957
1089
async validateRequestBody ( userCreateDto ) {
0 commit comments