rez_core 2.2.166 → 2.2.169

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/app.module.js +2 -0
  2. package/dist/app.module.js.map +1 -1
  3. package/dist/module/communication/controller/communication.controller.d.ts +4 -1
  4. package/dist/module/communication/controller/communication.controller.js +23 -3
  5. package/dist/module/communication/controller/communication.controller.js.map +1 -1
  6. package/dist/module/communication/entity/communication-config.entity.js +1 -1
  7. package/dist/module/communication/entity/communication-config.entity.js.map +1 -1
  8. package/dist/module/communication/entity/communication-hub.entity.js +1 -1
  9. package/dist/module/communication/entity/communication-hub.entity.js.map +1 -1
  10. package/dist/module/communication/service/communication.service.d.ts +5 -1
  11. package/dist/module/communication/service/communication.service.js +13 -3
  12. package/dist/module/communication/service/communication.service.js.map +1 -1
  13. package/dist/module/communication/strategies/email/gmail-api.strategy.d.ts +3 -0
  14. package/dist/module/communication/strategies/email/gmail-api.strategy.js +33 -12
  15. package/dist/module/communication/strategies/email/gmail-api.strategy.js.map +1 -1
  16. package/dist/module/communication/strategies/gmail.strategy.d.ts +3 -0
  17. package/dist/module/communication/strategies/gmail.strategy.js +17 -7
  18. package/dist/module/communication/strategies/gmail.strategy.js.map +1 -1
  19. package/dist/module/listmaster/service/list-master.service.js +0 -7
  20. package/dist/module/listmaster/service/list-master.service.js.map +1 -1
  21. package/dist/module/meta/service/entity-service-impl.service.js +0 -1
  22. package/dist/module/meta/service/entity-service-impl.service.js.map +1 -1
  23. package/dist/module/notification/controller/notification.controller.d.ts +17 -0
  24. package/dist/module/notification/controller/notification.controller.js +48 -0
  25. package/dist/module/notification/controller/notification.controller.js.map +1 -0
  26. package/dist/module/notification/controller/otp.controller.d.ts +2 -1
  27. package/dist/module/notification/controller/otp.controller.js +2 -2
  28. package/dist/module/notification/controller/otp.controller.js.map +1 -1
  29. package/dist/module/notification/entity/notification.entity.d.ts +8 -0
  30. package/dist/module/notification/entity/notification.entity.js +41 -0
  31. package/dist/module/notification/entity/notification.entity.js.map +1 -0
  32. package/dist/module/notification/firebase-admin.config.d.ts +2 -0
  33. package/dist/module/notification/firebase-admin.config.js +10 -0
  34. package/dist/module/notification/firebase-admin.config.js.map +1 -0
  35. package/dist/module/notification/firebase-admin.json +13 -0
  36. package/dist/module/notification/notification.module.js +7 -4
  37. package/dist/module/notification/notification.module.js.map +1 -1
  38. package/dist/module/notification/service/firebase.service.d.ts +11 -0
  39. package/dist/module/notification/service/firebase.service.js +40 -0
  40. package/dist/module/notification/service/firebase.service.js.map +1 -0
  41. package/dist/module/notification/service/otp.service.d.ts +2 -1
  42. package/dist/module/notification/service/otp.service.js +8 -3
  43. package/dist/module/notification/service/otp.service.js.map +1 -1
  44. package/dist/module/user/controller/login.controller.js +16 -4
  45. package/dist/module/user/controller/login.controller.js.map +1 -1
  46. package/dist/module/user/controller/user.controller.d.ts +1 -9
  47. package/dist/module/user/controller/user.controller.js +10 -4
  48. package/dist/module/user/controller/user.controller.js.map +1 -1
  49. package/dist/module/user/entity/user.entity.d.ts +1 -0
  50. package/dist/module/user/entity/user.entity.js +4 -0
  51. package/dist/module/user/entity/user.entity.js.map +1 -1
  52. package/dist/module/user/service/login.service.d.ts +17 -3
  53. package/dist/module/user/service/login.service.js +14 -5
  54. package/dist/module/user/service/login.service.js.map +1 -1
  55. package/dist/module/user/service/user.service.d.ts +7 -10
  56. package/dist/module/user/service/user.service.js +23 -8
  57. package/dist/module/user/service/user.service.js.map +1 -1
  58. package/dist/module/workflow/entity/task-data.entity.d.ts +2 -0
  59. package/dist/module/workflow/entity/task-data.entity.js +9 -1
  60. package/dist/module/workflow/entity/task-data.entity.js.map +1 -1
  61. package/dist/module/workflow/repository/task.repository.js +6 -1
  62. package/dist/module/workflow/repository/task.repository.js.map +1 -1
  63. package/dist/module/workflow/service/task.service.d.ts +4 -1
  64. package/dist/module/workflow/service/task.service.js +46 -2
  65. package/dist/module/workflow/service/task.service.js.map +1 -1
  66. package/dist/module/workflow/workflow.module.js +2 -0
  67. package/dist/module/workflow/workflow.module.js.map +1 -1
  68. package/dist/tsconfig.build.tsbuildinfo +1 -1
  69. package/package.json +4 -1
  70. package/src/app.module.ts +2 -0
  71. package/src/module/communication/controller/communication.controller.ts +19 -1
  72. package/src/module/communication/entity/communication-config.entity.ts +1 -1
  73. package/src/module/communication/entity/communication-hub.entity.ts +1 -1
  74. package/src/module/communication/service/communication.service.ts +21 -2
  75. package/src/module/communication/strategies/email/gmail-api.strategy.ts +37 -13
  76. package/src/module/communication/strategies/gmail.strategy.ts +15 -9
  77. package/src/module/listmaster/service/list-master.service.ts +0 -12
  78. package/src/module/meta/service/entity-service-impl.service.ts +0 -1
  79. package/src/module/notification/controller/notification.controller.ts +25 -0
  80. package/src/module/notification/controller/otp.controller.ts +3 -2
  81. package/src/module/notification/entity/notification.entity.ts +20 -0
  82. package/src/module/notification/firebase-admin.config.ts +8 -0
  83. package/src/module/notification/firebase-admin.json +13 -0
  84. package/src/module/notification/notification.module.ts +7 -4
  85. package/src/module/notification/service/firebase.service.ts +31 -0
  86. package/src/module/notification/service/otp.service.ts +9 -3
  87. package/src/module/user/controller/login.controller.ts +26 -11
  88. package/src/module/user/controller/user.controller.ts +7 -2
  89. package/src/module/user/entity/user.entity.ts +3 -0
  90. package/src/module/user/service/login.service.ts +24 -8
  91. package/src/module/user/service/user.service.ts +32 -6
  92. package/src/module/workflow/entity/task-data.entity.ts +7 -1
  93. package/src/module/workflow/repository/task.repository.ts +10 -2
  94. package/src/module/workflow/service/task.service.ts +56 -0
  95. package/src/module/workflow/workflow.module.ts +2 -0
  96. package/tsconfig.json +5 -4
@@ -31,17 +31,22 @@ export class LoginService {
31
31
  @Inject('ListMasterService')
32
32
  private readonly listMasterService: ListMasterService,
33
33
  private readonly jwtAuthService: JwtAuthService,
34
+ @InjectRepository(UserData)
35
+ private readonly userRepository: Repository<UserData>,
34
36
  ) {}
35
37
 
36
38
  masterKey: string = this.configService.get('MASTER_KEY') || '';
37
39
  masterIv: string = this.configService.get('MASTER_IV') || '';
38
40
 
39
- async login(
40
- email: string,
41
- password?: string,
42
- is_otp = false,
43
- subdomain?: string,
44
- ) {
41
+ async login(data: {
42
+ email: string;
43
+ password?: string;
44
+ subdomain: string;
45
+ fcm_token: string;
46
+ is_otp?: boolean;
47
+ }) {
48
+ const { email, password, is_otp = false, subdomain, fcm_token } = data;
49
+
45
50
  let organization;
46
51
 
47
52
  // 🔹 Step 1: If subdomain is provided, resolve the organization
@@ -63,6 +68,10 @@ export class LoginService {
63
68
  throw new BadRequestException('User not found in organization.');
64
69
  }
65
70
 
71
+ if (fcm_token) {
72
+ await this.userRepository.update({ id: user.id }, { fcm_token });
73
+ }
74
+
66
75
  // 🔹 Step 3: Verify org status
67
76
  const userOrgData = await this.organizationRepository.findOrganizationById(
68
77
  user.organization_id,
@@ -245,7 +254,14 @@ export class LoginService {
245
254
  );
246
255
  }
247
256
 
248
- async loginWithGoogle(email: string, name) {
257
+ async loginWithGoogle(data: {
258
+ email: string;
259
+ password: string;
260
+ name;
261
+ subdomain: string;
262
+ fcm_token: string;
263
+ }) {
264
+ const { email, password, name, subdomain, fcm_token } = data;
249
265
  const user = await this.userService.findByEmailId(email);
250
266
 
251
267
  if (!user) {
@@ -269,7 +285,7 @@ export class LoginService {
269
285
  }
270
286
 
271
287
  // Create session (Same as JWT login flow)
272
- return await this.login(email, undefined, true);
288
+ return await this.login(data);
273
289
  }
274
290
 
275
291
  async logout(sessionKey: string) {
@@ -19,12 +19,14 @@ import {
19
19
  import { CreateUserDto } from '../dto/create-user.dto';
20
20
  import { UserRoleMappingService } from './user-role-mapping.service';
21
21
  import { UserRoleMapping } from '../entity/user-role-mapping.entity';
22
- import { EntityManager } from 'typeorm';
22
+ import { EntityManager, Repository } from 'typeorm';
23
23
  import { UpdateUserDto } from '../dto/update-user.dto';
24
24
  import { ConfigService } from '@nestjs/config';
25
25
  // import { UserAppMappingService } from 'src/module/meta/service/user-app-mapping.service';
26
26
  import { ServiceResult } from 'src/dtos/response.dto';
27
27
  import { ListMasterService } from 'src/module/listmaster/service/list-master.service';
28
+ import { OrganizationRepository } from 'src/module/enterprise/repository/organization.repository';
29
+ import { InjectRepository } from '@nestjs/typeorm';
28
30
 
29
31
  @Injectable()
30
32
  export class UserService extends EntityServiceImpl {
@@ -33,6 +35,7 @@ export class UserService extends EntityServiceImpl {
33
35
  private userRoleMappingService: UserRoleMappingService,
34
36
  private readonly clockIDGenService: ClockIDGenService,
35
37
  private configService: ConfigService,
38
+ private readonly organizationRepository: OrganizationRepository,
36
39
  // private readonly userAppMappingService: UserAppMappingService,
37
40
  @Inject('RoleService') private readonly roleService: RoleService,
38
41
  @Inject('ListMasterService')
@@ -53,7 +56,7 @@ export class UserService extends EntityServiceImpl {
53
56
 
54
57
  let existingUser = await this.userRepository.findByEmailId(
55
58
  userData.email_id,
56
- // loggedInUser?.organization_id,
59
+ loggedInUser?.organization_id,
57
60
  );
58
61
  if (existingUser) {
59
62
  return { success: false, error: 'User with this email already exists' };
@@ -61,7 +64,7 @@ export class UserService extends EntityServiceImpl {
61
64
 
62
65
  existingUser = await this.userRepository.findByMobile(
63
66
  userData.mobile,
64
- // loggedInUser?.organization_id,
67
+ loggedInUser?.organization_id,
65
68
  );
66
69
  if (existingUser) {
67
70
  return { success: false, error: 'User with this mobile already exists' };
@@ -298,13 +301,36 @@ export class UserService extends EntityServiceImpl {
298
301
  await this.userRepository.saveUser(user); // This persists the updated field
299
302
  }
300
303
 
301
- async checkEmailExists(email: string) {
302
- if (!email) {
303
- return { success: false, message: 'Email is required' };
304
+ async checkEmailExists(data: {
305
+ email: string;
306
+ subdomain: string;
307
+ }): Promise<any> {
308
+ const { email, subdomain } = data;
309
+
310
+ if (!email || !subdomain) {
311
+ return { success: false, message: 'Email and Subdomain is required' };
304
312
  }
305
313
 
314
+ let organization;
315
+
316
+ if (subdomain) {
317
+ organization =
318
+ await this.organizationRepository.findOrganizationBySubdomain(
319
+ subdomain,
320
+ );
321
+
322
+ if (!organization) {
323
+ throw new BadRequestException('Organization not found.');
324
+ }
325
+ }
326
+
327
+ // 🔹 Step 2: Find the user by email + organization check
306
328
  const user = await this.userRepository.findByEmailId(email);
307
329
 
330
+ if (!user || (organization && user.organization_id !== organization.id)) {
331
+ throw new BadRequestException('User not found in organization.');
332
+ }
333
+
308
334
  if (user) {
309
335
  return {
310
336
  success: true,
@@ -56,7 +56,7 @@ export class TaskDataEntity extends BaseEntity {
56
56
  @Column({ nullable: true })
57
57
  due_date: Date;
58
58
 
59
- @Column({ nullable: true, type: 'varchar' })
59
+ @Column({ nullable: true, type: 'time' })
60
60
  due_time: string;
61
61
 
62
62
  @Column({ nullable: true, type: 'varchar' })
@@ -67,4 +67,10 @@ export class TaskDataEntity extends BaseEntity {
67
67
 
68
68
  @Column({ nullable: true, type: 'varchar' })
69
69
  category: string;
70
+
71
+ @Column({ nullable: true })
72
+ remainder_date: Date;
73
+
74
+ @Column({ nullable: true, type: 'varchar' })
75
+ remainder_time: string;
70
76
  }
@@ -50,6 +50,13 @@ export class TaskRepository {
50
50
  [act.action_requirement, loggedInUser.organization_id],
51
51
  );
52
52
 
53
+ const now = new Date();
54
+
55
+ const dueDateTime = new Date(now.setDate(now.getDate() + 2));
56
+
57
+ const due_date = dueDateTime.toISOString().split('T')[0];
58
+ const due_time = dueDateTime.toTimeString().split(' ')[0];
59
+
53
60
  const taskData = this.TaskRepository.create({
54
61
  stage_id: act.stage_id,
55
62
  user_id: loggedInUser.id,
@@ -60,12 +67,13 @@ export class TaskRepository {
60
67
  is_mandatory: is_mandatory[0]?.code === 'mandatory' ? true : false,
61
68
  mapped_entity_id,
62
69
  mapped_entity_type,
63
- due_date: new Date(new Date().setDate(new Date().getDate() + 2)),
70
+ due_date,
71
+ due_time,
64
72
  is_system: true,
65
73
  status: todoListMasterItemId[0]?.id,
66
74
  category: act?.action_category_code,
67
75
  task_owner: leadData[0]?.lead_owner,
68
- } as TaskDataEntity);
76
+ });
69
77
  await this.TaskRepository.save(taskData);
70
78
  }
71
79
  }
@@ -8,6 +8,8 @@ import { BaseEntity } from 'src/module/meta/entity/base-entity.entity';
8
8
  import { ActivityLogService } from './activity-log.service';
9
9
  import { ACTIVITY_CATEGORIES } from '../repository/activity-log.repository';
10
10
  import { MediaDataService } from 'src/module/meta/service/media-data.service';
11
+ import { Cron, CronExpression } from '@nestjs/schedule';
12
+ import { NotificationsService } from 'src/module/notification/service/firebase.service';
11
13
 
12
14
  @Injectable()
13
15
  export class TaskService extends EntityServiceImpl {
@@ -18,6 +20,7 @@ export class TaskService extends EntityServiceImpl {
18
20
  @Inject('ActivityLogService')
19
21
  private readonly activityLogService: ActivityLogService,
20
22
  private readonly mediaDataService: MediaDataService,
23
+ private readonly notificationsService: NotificationsService, // 👈 inject here
21
24
  ) {
22
25
  super();
23
26
  }
@@ -438,4 +441,57 @@ export class TaskService extends EntityServiceImpl {
438
441
  console.log(notePayload);
439
442
  return await super.createEntity(notePayload, loggedInUser);
440
443
  }
444
+
445
+ @Cron(CronExpression.EVERY_30_MINUTES)
446
+ async fetchTasksDueIn30Mins() {
447
+ const now = new Date();
448
+ const in30Min = new Date(now.getTime() + 30 * 60 * 1000);
449
+
450
+ const completedStatus = await this.dataSource.query(
451
+ `SELECT id FROM cr_list_master_items WHERE name = 'completed' AND listtype = 'TKST' LIMIT 1;`,
452
+ );
453
+ const completedId = completedStatus[0]?.id;
454
+
455
+ const tasks = await this.dataSource.query(
456
+ `
457
+ SELECT *
458
+ FROM cr_wf_task_data
459
+ WHERE status != ?
460
+ AND TIMESTAMP(due_date, due_time) BETWEEN ? AND ?
461
+ `,
462
+ [completedId, now, in30Min],
463
+ );
464
+
465
+ if (!tasks.length) {
466
+ console.log('No tasks due in 30 mins');
467
+ return;
468
+ }
469
+
470
+ for (const task of tasks) {
471
+ const message = `Reminder: Task ${task.name} is due at ${task.due_time}`;
472
+
473
+ await this.dataSource.query(
474
+ `
475
+ INSERT INTO cr_notification (user_id, event_type, message, entity_type, organization_id, created_date, mapped_entity_id, mapped_entity_type, level_id, level_type)
476
+ VALUES (?, ?, ?, ?, ?, NOW(), ?, ?, ?, ?)
477
+ `,
478
+ [
479
+ task.task_owner,
480
+ 'Task Remainder',
481
+ message,
482
+ 'NOTF',
483
+ task.organization_id,
484
+ task.mapped_entity_id,
485
+ task.mapped_entity_type,
486
+ task.level_id,
487
+ task.level_type,
488
+ ],
489
+ );
490
+ await this.notificationsService.sendToUser(
491
+ String(task.task_owner), // userId as string
492
+ 'Task Reminder',
493
+ message,
494
+ );
495
+ }
496
+ }
441
497
  }
@@ -62,6 +62,7 @@ import { ActivityLog } from './entity/activity-log.entity';
62
62
  import { ActivityLogService } from './service/activity-log.service';
63
63
  import { ActivityLogRepository } from './repository/activity-log.repository';
64
64
  import { ActivityLogController } from './controller/activity-log.controller';
65
+ import { NotificationModule } from '../notification/notification.module';
65
66
 
66
67
  @Module({
67
68
  imports: [
@@ -87,6 +88,7 @@ import { ActivityLogController } from './controller/activity-log.controller';
87
88
  ]),
88
89
  EntityModule,
89
90
  ListMasterModule,
91
+ NotificationModule,
90
92
  ],
91
93
  providers: [
92
94
  { provide: 'ActionCategoryService', useClass: ActionCategoryService },
package/tsconfig.json CHANGED
@@ -16,8 +16,9 @@
16
16
  "forceConsistentCasingInFileNames": true,
17
17
  "noImplicitAny": false,
18
18
  "strictBindCallApply": false,
19
- "noFallthroughCasesInSwitch": false
20
- },
21
- "include": ["src/**/*"],
22
- "exclude": ["node_modules", "dist", "test"]
19
+ "noFallthroughCasesInSwitch": false,
20
+ "resolveJsonModule": true,
21
+ },
22
+ "include": ["src/**/*"],
23
+ "exclude": ["node_modules", "dist", "test"]
23
24
  }