rez_core 2.2.224 → 2.2.225

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.
@@ -0,0 +1,177 @@
1
+ # Communication Module Documentation
2
+
3
+ ## Database Schema
4
+
5
+ ### Tables: cr_communication_config & cr_communication_hub
6
+ ```sql
7
+ -- Configuration storage
8
+ CREATE TABLE cr_communication_config (
9
+ id INT AUTO_INCREMENT PRIMARY KEY,
10
+ config_json JSON NOT NULL,
11
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
12
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
13
+ );
14
+
15
+ -- Hub mapping level->provider
16
+ CREATE TABLE cr_communication_hub (
17
+ id INT AUTO_INCREMENT PRIMARY KEY,
18
+ level_id INT NOT NULL,
19
+ level_type VARCHAR(100) NOT NULL, -- 'organization', 'department', 'user', 'project'
20
+ status TINYINT DEFAULT 1,
21
+ config_id INT NOT NULL,
22
+ communication_config_type ENUM('WA','SMS','EMAIL','TELEPHONE') NOT NULL,
23
+ service VARCHAR(100) NOT NULL, -- API, THIRD_PARTY, SMTP
24
+ provider VARCHAR(100) NOT NULL, -- gmail, outlook, twilio, whatsapp, etc.
25
+ priority INT DEFAULT 1,
26
+ is_default BOOLEAN DEFAULT FALSE,
27
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
28
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
29
+ INDEX idx_level_status (level_id, level_type, status),
30
+ INDEX idx_config_type (communication_config_type)
31
+ );
32
+ ```
33
+
34
+ ## Architecture: Hierarchical Factory Pattern
35
+
36
+ ### Strategy Interface
37
+ ```ts
38
+ export interface CommunicationStrategy {
39
+ sendMessage(to: string, message: string, config: any): Promise<any>;
40
+ }
41
+ ```
42
+
43
+ ### Factory Structure (Mode → Service → Provider)
44
+ - **EMAIL**: API (gmail, outlook, aws-ses) | SMTP (gmail, outlook, sendgrid, generic)
45
+ - **SMS**: THIRD_PARTY (twilio, knowlarity)
46
+ - **WA**: API (whatsapp)
47
+ - **TELEPHONE**: THIRD_PARTY (knowlarity)
48
+
49
+ ### Main Factory
50
+ ```ts
51
+ @Injectable()
52
+ export class CommunicationFactory {
53
+ create(mode: string, service: string, provider: string): CommunicationStrategy {
54
+ // Returns appropriate strategy instance
55
+ }
56
+
57
+ getAllSupportedCombinations(): Array<{mode, service, provider}> {}
58
+ getSupportedCombinationsForMode(mode: string): Array<{service, provider}> {}
59
+ validateCombination(mode: string, service: string, provider: string): boolean {}
60
+ }
61
+ ```
62
+
63
+ ### Service Layer
64
+ ```ts
65
+ @Injectable()
66
+ export class CommunicationService {
67
+ // Main send with fallback
68
+ async send(orgId: number, to: string, message: string, type?: string, options: any = {}) {}
69
+
70
+ // Type-specific methods
71
+ async sendEmail(orgId: number, to: string, subject: string, body: string, attachments?: any[]) {}
72
+ async sendSMS(orgId: number, to: string, message: string) {}
73
+ async sendWhatsApp(orgId: number, to: string, message: string, mediaUrl?: string) {}
74
+
75
+ // Bulk & template support
76
+ async sendBulk(orgId: number, recipients: string[], message: string, type?: string) {}
77
+ async sendWithTemplate(orgId: number, to: string, templateId: string, variables: any) {}
78
+
79
+ // Configuration management
80
+ async createConfiguration(orgId: number, configData: any) {}
81
+ async updateConfiguration(hubId: number, configData: any) {}
82
+ async setDefaultProvider(hubId: number) {}
83
+ }
84
+ ```
85
+
86
+ ## Provider Configuration Examples
87
+
88
+ ### Gmail API
89
+ ```json
90
+ {
91
+ "type": "EMAIL", "service": "API", "provider": "gmail",
92
+ "config": {
93
+ "clientId": "your-client-id.apps.googleusercontent.com",
94
+ "clientSecret": "your-client-secret",
95
+ "refreshToken": "your-refresh-token",
96
+ "accessToken": "your-access-token"
97
+ }
98
+ }
99
+ ```
100
+
101
+ ### Gmail SMTP
102
+ ```json
103
+ {
104
+ "type": "EMAIL", "service": "SMTP", "provider": "gmail",
105
+ "config": {
106
+ "email": "your-email@gmail.com",
107
+ "password": "your-app-password",
108
+ "subject": "Default Subject"
109
+ }
110
+ }
111
+ ```
112
+
113
+ ### Twilio SMS
114
+ ```json
115
+ {
116
+ "type": "SMS", "service": "THIRD_PARTY", "provider": "twilio",
117
+ "config": {
118
+ "accountSid": "your-twilio-account-sid",
119
+ "authToken": "your-twilio-auth-token",
120
+ "fromNumber": "+1234567890"
121
+ }
122
+ }
123
+ ```
124
+
125
+ ### WhatsApp Cloud API
126
+ ```json
127
+ {
128
+ "type": "WA", "service": "API", "provider": "whatsapp",
129
+ "config": {
130
+ "accessToken": "your-whatsapp-access-token",
131
+ "phoneNumberId": "your-phone-number-id",
132
+ "apiVersion": "v17.0"
133
+ }
134
+ }
135
+ ```
136
+
137
+ ### Knowlarity Voice
138
+ ```json
139
+ {
140
+ "type": "TELEPHONE", "service": "THIRD_PARTY", "provider": "knowlarity",
141
+ "config": {
142
+ "apiKey": "your-knowlarity-api-key",
143
+ "apiSecret": "your-knowlarity-api-secret",
144
+ "callerNumber": "your-knowlarity-number",
145
+ "callType": "voice",
146
+ "language": "en"
147
+ }
148
+ }
149
+ ```
150
+
151
+ ## API Endpoints
152
+
153
+ ```
154
+ POST /communication/send
155
+ POST /communication/config
156
+ GET /communication/level/:id/:type/configs
157
+ POST /communication/gmail/oauth/init
158
+ POST /communication/oauth/callback/gmail
159
+ ```
160
+
161
+ ## Module Structure
162
+ ```
163
+ src/module/communication/
164
+ ├── controller/communication.controller.ts
165
+ ├── entity/communication-{config,hub,log}.entity.ts
166
+ ├── service/communication.service.ts
167
+ ├── factories/communication.factory.ts
168
+ ├── strategies/gmail.strategy.ts (and others)
169
+ └── communication.module.ts
170
+ ```
171
+
172
+ ## Level Hierarchy (fallback order)
173
+ 1. **user** (highest priority)
174
+ 2. **team**
175
+ 3. **project**
176
+ 4. **department**
177
+ 5. **organization** (lowest priority)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez_core",
3
- "version": "2.2.224",
3
+ "version": "2.2.225",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "private": false,
package/src/app.module.ts CHANGED
@@ -18,6 +18,7 @@ import { IcsMeetingModule } from './module/ics/ics.module';
18
18
  import { DashboardModule } from './module/dashboard/dashboard.module';
19
19
  import { CommunicationModule } from './module/communication/communication.module';
20
20
  import { ScheduleModule } from '@nestjs/schedule';
21
+ import { AuthModule } from './module/auth/auth.module';
21
22
 
22
23
  @Module({
23
24
  imports: [
@@ -39,6 +40,7 @@ import { ScheduleModule } from '@nestjs/schedule';
39
40
  IcsMeetingModule,
40
41
  DashboardModule,
41
42
  CommunicationModule,
43
+ AuthModule,
42
44
  ScheduleModule.forRoot(),
43
45
  ],
44
46
  })
@@ -10,6 +10,9 @@ import { PassportModule } from '@nestjs/passport';
10
10
  import { UserSession } from '../user/entity/user-session.entity';
11
11
  import { GoogleStrategy } from './strategies/google.strategy';
12
12
  import { RolesGuard } from './guards/role.guard';
13
+ import { AuthService } from './services/auth.service';
14
+ import { AuthController } from './controller/auth.controller';
15
+ import { UserModule } from '../user/user.module';
13
16
 
14
17
  @Module({
15
18
  imports: [
@@ -30,16 +33,17 @@ import { RolesGuard } from './guards/role.guard';
30
33
  };
31
34
  },
32
35
  }),
33
-
34
36
  TypeOrmModule.forFeature([UserSession]),
35
37
  ],
38
+ controllers: [AuthController],
36
39
  providers: [
37
40
  JwtAuthService,
38
41
  JwtStrategy,
39
42
  JwtAuthGuard,
40
43
  GoogleStrategy,
41
44
  RolesGuard,
45
+ AuthService,
42
46
  ],
43
- exports: [JwtAuthService, JwtAuthGuard, RolesGuard],
47
+ exports: [JwtAuthService, JwtAuthGuard, RolesGuard, AuthService],
44
48
  })
45
49
  export class AuthModule {}
@@ -0,0 +1,28 @@
1
+ import { Body, Controller, Post, Req, UseGuards } from '@nestjs/common';
2
+ import { JwtAuthGuard } from 'src/module/auth/guards/jwt.guard';
3
+ import { AuthService } from '../services/auth.service';
4
+ import { UAParser } from 'ua-parser-js';
5
+
6
+ @Controller('auth')
7
+ export class AuthController {
8
+ constructor(private readonly authService: AuthService) {}
9
+
10
+ @Post('fcmtoken')
11
+ @UseGuards(JwtAuthGuard)
12
+ async getDashboard(@Req() req: any, @Body('fcmtoken') fcmtoken: string) {
13
+ const loggedInUser = req.user.userData;
14
+
15
+ const ip =
16
+ (req.headers['x-forwarded-for'] as string)?.split(',')[0].trim() ||
17
+ req.socket.remoteAddress ||
18
+ req.ip ||
19
+ '';
20
+
21
+ const userAgent = req.headers['user-agent'] || '';
22
+ const parser = new UAParser(userAgent);
23
+ const browser = parser.getBrowser().name || 'Unknown';
24
+ const os = parser.getOS().name || 'Unknown';
25
+
26
+ return this.authService.fcmtoken(fcmtoken, loggedInUser, ip, browser, os);
27
+ }
28
+ }
@@ -1,29 +1,50 @@
1
- import { BadRequestException, Injectable } from '@nestjs/common';
1
+ import { BadRequestException, Inject, Injectable } from '@nestjs/common';
2
2
  import { UserService } from '../../user/service/user.service';
3
3
  import { JwtService } from '@nestjs/jwt';
4
4
  import { UserData } from '../../user/entity/user.entity';
5
+ import { DataSource } from 'typeorm';
5
6
 
6
7
  @Injectable()
7
8
  export class AuthService {
8
9
  constructor(
9
- private userService: UserService,
10
10
  private jwtService: JwtService,
11
+ private dataSource: DataSource,
11
12
  ) {}
12
13
 
13
- async validateUser(email: string, password: string): Promise<UserData> {
14
- const user = await this.userService.findByEmailId(email);
15
- if (!user) {
16
- throw new BadRequestException('User not found');
17
- }
18
- const isMatch: boolean = password === user.password;
19
- if (!isMatch) {
20
- throw new BadRequestException('Password does not match');
21
- }
22
- return user;
23
- }
14
+ // async validateUser(email: string, password: string): Promise<UserData> {
15
+ // const user = await this.userService.findByEmailId(email);
16
+ // if (!user) {
17
+ // throw new BadRequestException('User not found');
18
+ // }
19
+ // const isMatch: boolean = password === user.password;
20
+ // if (!isMatch) {
21
+ // throw new BadRequestException('Password does not match');
22
+ // }
23
+ // return user;
24
+ // }
24
25
 
25
26
  async login(user: UserData) {
26
27
  const payload = { email: user.email_id, id: user.id };
27
28
  return { access_token: this.jwtService.sign(payload) };
28
29
  }
30
+
31
+ async fcmtoken(
32
+ fcmtoken: string,
33
+ loggedInUser: any,
34
+ ip: string,
35
+ browser: string,
36
+ os: string,
37
+ ) {
38
+ const { id: userId, organization_id } = loggedInUser;
39
+
40
+ // Update the cr_user table
41
+ await this.dataSource.query(
42
+ `UPDATE cr_user
43
+ SET fcm_token = ?, ip = ?, browser = ?, os = ?
44
+ WHERE id = ? AND organization_id = ?`,
45
+ [fcmtoken, ip, browser, os, userId, organization_id],
46
+ );
47
+
48
+ return { message: 'FCM token updated successfully' };
49
+ }
29
50
  }
@@ -50,7 +50,12 @@ import { WebhookController } from './controller/webhook.controller';
50
50
  TypeOrmModule.forFeature([CommunicationConfig, CommunicationHub]),
51
51
  IcsMeetingModule,
52
52
  ],
53
- controllers: [CommunicationController, GoogleController, WrapperController, WebhookController],
53
+ controllers: [
54
+ CommunicationController,
55
+ GoogleController,
56
+ WrapperController,
57
+ WebhookController,
58
+ ],
54
59
  providers: [
55
60
  // Main Services
56
61
  CommunicationService,
@@ -0,0 +1,32 @@
1
+ import { ACTION_CATEGORY } from 'src/constant/global.constant';
2
+ import { BaseEntity } from 'src/module/meta/entity/base-entity.entity';
3
+ import { Column, Entity } from 'typeorm';
4
+
5
+ @Entity({ name: 'cr_rule_' })
6
+ export class ActionCategory extends BaseEntity {
7
+ constructor() {
8
+ super();
9
+ this.entity_type = ACTION_CATEGORY;
10
+ }
11
+
12
+ @Column({ type: 'varchar', nullable: true })
13
+ logo: string;
14
+
15
+ @Column({ type: 'varchar', nullable: true })
16
+ modalName: string;
17
+
18
+ @Column({ type: 'varchar', nullable: true })
19
+ mapped_entity_type: string;
20
+
21
+ @Column({ type: 'varchar', nullable: true })
22
+ reason_code: string;
23
+
24
+ @Column({ type: 'boolean', nullable: true })
25
+ is_template: boolean;
26
+
27
+ @Column({ type: 'boolean', nullable: true })
28
+ is_form: boolean;
29
+
30
+ @Column({ type: 'boolean', nullable: true })
31
+ is_assignment: boolean;
32
+ }