rez_core 4.0.98 → 4.0.99
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.
- package/.prettierrc +3 -3
- package/.vscode/extensions.json +5 -0
- package/README.md +99 -99
- package/dist/module/auth/guards/role.guard.js +3 -3
- package/dist/module/auth/services/auth.service.js +2 -2
- package/dist/module/filter/repository/saved-filter.repository.js +4 -4
- package/dist/module/filter/service/filter-evaluator.service.js +2 -2
- package/dist/module/filter/service/filter.service.js +22 -22
- package/dist/module/integration/examples/usage.example.js +9 -9
- package/dist/module/integration/service/integration.service.js +1 -1
- package/dist/module/integration/service/wrapper.service.js +25 -25
- package/dist/module/listmaster/service/list-master-item.service.js +2 -2
- package/dist/module/mapper/service/field-mapper.service.js +4 -4
- package/dist/module/mapper/service/mapper.service.js +2 -2
- package/dist/module/meta/service/entity-dynamic.service.js +26 -20
- package/dist/module/meta/service/entity-dynamic.service.js.map +1 -1
- package/dist/module/meta/service/entity-list.service.js +3 -3
- package/dist/module/meta/service/entity-master.service.js +3 -3
- package/dist/module/meta/service/entity-relation.service.js +11 -11
- package/dist/module/meta/service/entity-service-impl.service.js +3 -3
- package/dist/module/meta/service/resolver.service.js +3 -3
- package/dist/module/module/repository/menu.repository.js +12 -12
- package/dist/module/notification/service/notification.service.js +9 -9
- package/dist/module/user/controller/login.controller.js +18 -18
- package/dist/module/user/service/role.service.js +4 -4
- package/dist/module/user/service/user-session.service.js +2 -2
- package/dist/module/workflow/repository/action.repository.js +20 -20
- package/dist/module/workflow/repository/comm-template.repository.js +6 -6
- package/dist/module/workflow/repository/form-master.repository.js +2 -2
- package/dist/module/workflow/repository/stage-group.repository.js +23 -23
- package/dist/module/workflow/repository/stage-movement.repository.js +15 -15
- package/dist/module/workflow/repository/stage.repository.js +8 -8
- package/dist/module/workflow/service/action-template-mapping.service.js +22 -22
- package/dist/module/workflow/service/action.service.js +7 -7
- package/dist/module/workflow/service/entity-modification.service.js +6 -6
- package/dist/module/workflow/service/stage-group.service.js +2 -2
- package/dist/module/workflow/service/stage.service.js +2 -2
- package/dist/module/workflow/service/task.service.js +28 -28
- package/dist/module/workflow/service/workflow-list-master.service.js +15 -15
- package/dist/module/workflow/service/workflow-meta.service.js +35 -35
- package/dist/module/workflow/service/workflow.service.js +2 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/service/reflection-helper.service.js +2 -2
- package/docs/modules/event-driven-integration-design.md +91 -91
- package/docs/modules/integration.md +250 -250
- package/eslint.config.mjs +34 -34
- package/nest-cli.json +14 -14
- package/package.json +118 -118
- package/src/app.controller.ts +12 -12
- package/src/app.module.ts +49 -49
- package/src/app.service.ts +8 -8
- package/src/config/config.module.ts +18 -18
- package/src/config/database.config.ts +23 -23
- package/src/constant/global.constant.ts +67 -67
- package/src/core.module.ts +81 -81
- package/src/decorators/roles.decorator.ts +7 -7
- package/src/dtos/response.dto.ts +6 -6
- package/src/dtos/response.ts +5 -5
- package/src/index.ts +1 -1
- package/src/module/auth/auth.module.ts +49 -49
- package/src/module/auth/controller/auth.controller.ts +28 -28
- package/src/module/auth/guards/google-auth.guard.ts +9 -9
- package/src/module/auth/guards/jwt.guard.ts +22 -22
- package/src/module/auth/guards/role.guard.ts +68 -68
- package/src/module/auth/services/auth.service.ts +50 -50
- package/src/module/auth/services/jwt.service.ts +11 -11
- package/src/module/auth/strategies/google.strategy.ts +54 -54
- package/src/module/auth/strategies/jwt.strategy.ts +58 -58
- package/src/module/auth/strategies/local.strategy.ts +13 -13
- package/src/module/dashboard/controller/dashboard.controller.ts +36 -36
- package/src/module/dashboard/dashboard.module.ts +21 -21
- package/src/module/dashboard/entity/dashboard_page_data.entity.ts +27 -27
- package/src/module/dashboard/entity/widget_master.entity.ts +18 -18
- package/src/module/dashboard/repository/dashboard.repository.ts +42 -42
- package/src/module/dashboard/service/dashboard.service.ts +73 -73
- package/src/module/dev/dev.module.ts +12 -12
- package/src/module/dev/service/dev.service.ts +7 -7
- package/src/module/enterprise/controller/organization.controller.ts +36 -36
- package/src/module/enterprise/enterprise.module.ts +30 -30
- package/src/module/enterprise/entity/enterprise.entity.ts +37 -37
- package/src/module/enterprise/entity/organization-app-mapping.entity.ts +13 -13
- package/src/module/enterprise/entity/organization.entity.ts +92 -92
- package/src/module/enterprise/repository/enterprise.repository.ts +31 -31
- package/src/module/enterprise/repository/organization.repository.ts +26 -26
- package/src/module/enterprise/repository/school.repository.ts +278 -278
- package/src/module/enterprise/service/brand.service.ts +5 -5
- package/src/module/enterprise/service/enterprise.service.ts +16 -16
- package/src/module/enterprise/service/organization-app-mapping.service.ts +4 -4
- package/src/module/enterprise/service/organization.service.ts +145 -145
- package/src/module/filter/controller/filter.controller.ts +84 -84
- package/src/module/filter/dto/filter-request.dto.ts +38 -38
- package/src/module/filter/entity/saved-filter-detail.entity.ts +41 -41
- package/src/module/filter/entity/saved-filter-master.entity.ts +23 -23
- package/src/module/filter/filter.module.ts +31 -31
- package/src/module/filter/repository/saved-filter.repository.ts +168 -168
- package/src/module/filter/service/filter-evaluator.service.ts +86 -86
- package/src/module/filter/service/filter.service.ts +941 -941
- package/src/module/filter/service/saved-filter.service.ts +170 -170
- package/src/module/ics/controller/ics.controller.ts +21 -21
- package/src/module/ics/dto/ics.dto.ts +55 -55
- package/src/module/ics/ics.module.ts +13 -13
- package/src/module/ics/service/ics.service.ts +57 -57
- package/src/module/integration/controller/calender-event.controller.ts +31 -31
- package/src/module/integration/controller/integration.controller.ts +662 -662
- package/src/module/integration/controller/wrapper.controller.ts +37 -37
- package/src/module/integration/dto/create-config.dto.ts +526 -526
- package/src/module/integration/entity/integration-config.entity.ts +112 -112
- package/src/module/integration/entity/integration-entity-mapper.entity.ts +14 -14
- package/src/module/integration/entity/integration-source.entity.ts +17 -17
- package/src/module/integration/entity/user-integration.entity.ts +71 -71
- package/src/module/integration/examples/usage.example.ts +338 -338
- package/src/module/integration/factories/base.factory.ts +7 -7
- package/src/module/integration/factories/email.factory.ts +49 -49
- package/src/module/integration/factories/integration.factory.ts +121 -121
- package/src/module/integration/factories/sms.factory.ts +51 -51
- package/src/module/integration/factories/telephone.factory.ts +41 -41
- package/src/module/integration/factories/whatsapp.factory.ts +56 -56
- package/src/module/integration/integration.module.ts +110 -110
- package/src/module/integration/service/calendar-event.service.ts +118 -118
- package/src/module/integration/service/integration-entity-mapper.service.ts +17 -17
- package/src/module/integration/service/integration-queue.service.ts +229 -229
- package/src/module/integration/service/integration.service.ts +2633 -2633
- package/src/module/integration/service/oauth.service.ts +224 -224
- package/src/module/integration/service/wrapper.service.ts +493 -493
- package/src/module/integration/strategies/email/gmail-api.strategy.ts +280 -280
- package/src/module/integration/strategies/email/outlook-api.strategy.ts +44 -44
- package/src/module/integration/strategies/email/outlook.strategy.ts +64 -64
- package/src/module/integration/strategies/email/sendgrid-api.strategy.ts +260 -260
- package/src/module/integration/strategies/integration.strategy.ts +97 -97
- package/src/module/integration/strategies/sms/gupshup-sms.strategy.ts +146 -146
- package/src/module/integration/strategies/sms/msg91-sms.strategy.ts +164 -164
- package/src/module/integration/strategies/sms/tubelight-sms.strategy.ts +163 -163
- package/src/module/integration/strategies/telephone/ozonetel-voice.strategy.ts +238 -238
- package/src/module/integration/strategies/telephone/tubelight-voice.strategy.ts +210 -210
- package/src/module/integration/strategies/whatsapp/gupshup-whatsapp.strategy.ts +359 -359
- package/src/module/integration/strategies/whatsapp/tubelight-whatsapp.strategy.ts +372 -372
- package/src/module/integration/strategies/whatsapp/whatsapp-cloud.strategy.ts +403 -403
- package/src/module/integration/strategies/whatsapp/whatsapp.strategy.ts +57 -57
- package/src/module/layout/controller/layout.controller.ts +47 -47
- package/src/module/layout/entity/header-items.entity.ts +28 -28
- package/src/module/layout/entity/header-section.entity.ts +19 -19
- package/src/module/layout/layout.module.ts +21 -21
- package/src/module/layout/repository/header-items.repository.ts +18 -18
- package/src/module/layout/repository/header-section.repository.ts +22 -22
- package/src/module/layout/service/header-section.service.ts +25 -25
- package/src/module/layout_preference/controller/layout_preference.controller.ts +73 -73
- package/src/module/layout_preference/entity/layout_preference.entity.ts +28 -28
- package/src/module/layout_preference/layout_preference.module.ts +22 -22
- package/src/module/layout_preference/repository/layout_preference.repository.ts +65 -65
- package/src/module/layout_preference/service/layout_preference.service.ts +184 -184
- package/src/module/lead/controller/lead.controller.ts +30 -30
- package/src/module/lead/lead.module.ts +14 -14
- package/src/module/lead/repository/lead.repository.ts +41 -41
- package/src/module/lead/service/lead.service.ts +54 -54
- package/src/module/listmaster/controller/list-master.controller.ts +187 -187
- package/src/module/listmaster/entity/list-master-items.entity.ts +43 -43
- package/src/module/listmaster/entity/list-master.entity.ts +33 -33
- package/src/module/listmaster/listmaster.module.ts +44 -44
- package/src/module/listmaster/repository/list-master-items.repository.ts +169 -169
- package/src/module/listmaster/repository/list-master.repository.ts +46 -46
- package/src/module/listmaster/service/list-master-engine.ts +19 -19
- package/src/module/listmaster/service/list-master-extension.interface.ts +4 -4
- package/src/module/listmaster/service/list-master-item.service.ts +292 -292
- package/src/module/listmaster/service/list-master-registry.ts +15 -15
- package/src/module/listmaster/service/list-master.service.ts +441 -441
- package/src/module/mapper/controller/field-mapper.controller.ts +76 -76
- package/src/module/mapper/controller/mapper.controller.ts +20 -20
- package/src/module/mapper/dto/field-mapper.dto.ts +14 -14
- package/src/module/mapper/entity/field-lovs.entity.ts +19 -19
- package/src/module/mapper/entity/field-mapper.entity.ts +53 -53
- package/src/module/mapper/entity/mapper.entity.ts +16 -16
- package/src/module/mapper/mapper.module.ts +34 -34
- package/src/module/mapper/repository/field-lovs.repository.ts +35 -35
- package/src/module/mapper/repository/field-mapper.repository.ts +42 -42
- package/src/module/mapper/repository/mapper.repository.ts +15 -15
- package/src/module/mapper/service/field-mapper.service.ts +266 -266
- package/src/module/mapper/service/mapper.service.ts +79 -79
- package/src/module/master/controller/master.controller.ts +74 -74
- package/src/module/master/service/master.service.ts +483 -483
- package/src/module/meta/controller/app-master.controller.ts +38 -38
- package/src/module/meta/controller/attribute-master.controller.ts +66 -66
- package/src/module/meta/controller/entity-dynamic.controller.ts +125 -125
- package/src/module/meta/controller/entity-master.controller.ts +28 -28
- package/src/module/meta/controller/entity-relation.controller.ts +36 -36
- package/src/module/meta/controller/entity.controller.ts +392 -392
- package/src/module/meta/controller/entity.public.controller.ts +75 -75
- package/src/module/meta/controller/media.controller.ts +107 -107
- package/src/module/meta/controller/meta.controller.ts +96 -96
- package/src/module/meta/controller/view-master.controller.ts +86 -86
- package/src/module/meta/dto/entity-list-data.dto.ts +6 -6
- package/src/module/meta/dto/entity-tab.dto.ts +4 -4
- package/src/module/meta/dto/entity-table.dto.ts +9 -9
- package/src/module/meta/entity/app-master.entity.ts +34 -34
- package/src/module/meta/entity/attribute-master.entity.ts +89 -89
- package/src/module/meta/entity/base-entity.entity.ts +75 -75
- package/src/module/meta/entity/entity-master.entity.ts +85 -85
- package/src/module/meta/entity/entity-relation-data.entity.ts +29 -29
- package/src/module/meta/entity/entity-relation.entity.ts +23 -23
- package/src/module/meta/entity/entity-table-column.entity.ts +61 -61
- package/src/module/meta/entity/entity-table.entity.ts +50 -50
- package/src/module/meta/entity/media-data.entity.ts +32 -32
- package/src/module/meta/entity/preference.entity.ts +62 -62
- package/src/module/meta/entity/view-master.entity.ts +41 -41
- package/src/module/meta/entity.module.ts +158 -158
- package/src/module/meta/repository/app-master.repository.ts +20 -20
- package/src/module/meta/repository/attribute-master.repository.ts +110 -110
- package/src/module/meta/repository/entity-master.repository.ts +69 -69
- package/src/module/meta/repository/entity-table-column.repository.ts +39 -39
- package/src/module/meta/repository/entity-table.repository.ts +53 -53
- package/src/module/meta/repository/media-data.repository.ts +50 -50
- package/src/module/meta/repository/preference.repository.ts +20 -20
- package/src/module/meta/repository/user-app-mapping.repository.ts +28 -28
- package/src/module/meta/repository/view-master.repository.ts +42 -42
- package/src/module/meta/service/app-master.service.ts +37 -37
- package/src/module/meta/service/attribute-master.service.ts +117 -117
- package/src/module/meta/service/common.service.ts +9 -9
- package/src/module/meta/service/entity-dynamic.service.ts +819 -809
- package/src/module/meta/service/entity-list.service.ts +205 -205
- package/src/module/meta/service/entity-master.service.ts +169 -169
- package/src/module/meta/service/entity-realation-data.service.ts +9 -9
- package/src/module/meta/service/entity-relation.service.ts +69 -69
- package/src/module/meta/service/entity-service-impl.service.ts +525 -525
- package/src/module/meta/service/entity-table-column.service.ts +39 -39
- package/src/module/meta/service/entity-table.service.ts +150 -150
- package/src/module/meta/service/entity-validation.service.ts +187 -187
- package/src/module/meta/service/entity.service.ts +67 -67
- package/src/module/meta/service/field-group.service.ts +103 -103
- package/src/module/meta/service/media-data.service.ts +507 -507
- package/src/module/meta/service/populate-meta.service.ts +193 -193
- package/src/module/meta/service/preference.service.ts +16 -16
- package/src/module/meta/service/resolver.service.ts +267 -267
- package/src/module/meta/service/section-master.service.ts +104 -104
- package/src/module/meta/service/update-form-json.service.ts +22 -22
- package/src/module/meta/service/user-app-mapping.service.ts +17 -17
- package/src/module/meta/service/view-master.service.ts +127 -127
- package/src/module/module/controller/menu.controller.ts +15 -15
- package/src/module/module/controller/module-access.controller.ts +134 -134
- package/src/module/module/entity/menu.entity.ts +43 -43
- package/src/module/module/entity/module-access.entity.ts +25 -25
- package/src/module/module/entity/module-action.entity.ts +17 -17
- package/src/module/module/entity/module.entity.ts +52 -52
- package/src/module/module/module.module.ts +42 -42
- package/src/module/module/repository/menu.repository.ts +184 -184
- package/src/module/module/repository/module-access.repository.ts +344 -344
- package/src/module/module/service/menu.service.ts +82 -82
- package/src/module/module/service/module-access.service.ts +209 -209
- package/src/module/notification/controller/notification.controller.ts +58 -58
- package/src/module/notification/controller/otp.controller.ts +117 -117
- package/src/module/notification/entity/notification.entity.ts +26 -26
- package/src/module/notification/entity/otp.entity.ts +28 -28
- package/src/module/notification/firebase-admin.config.ts +22 -22
- package/src/module/notification/notification.module.ts +69 -69
- package/src/module/notification/repository/otp.repository.ts +27 -27
- package/src/module/notification/service/email.service.ts +127 -127
- package/src/module/notification/service/notification.service.ts +163 -163
- package/src/module/notification/service/otp.service.ts +132 -132
- package/src/module/third-party-module/entity/third-party-api-registry.entity.ts +52 -52
- package/src/module/third-party-module/repository/third-party-api-registry.repository.ts +20 -20
- package/src/module/third-party-module/service/api-registry.service.ts +13 -13
- package/src/module/third-party-module/third-party.module.ts +12 -12
- package/src/module/user/controller/login.controller.ts +197 -197
- package/src/module/user/controller/user.controller.ts +40 -40
- package/src/module/user/dto/create-user.dto.ts +62 -62
- package/src/module/user/dto/update-user.dto.ts +4 -4
- package/src/module/user/entity/role.entity.ts +33 -33
- package/src/module/user/entity/user-role-mapping.entity.ts +38 -38
- package/src/module/user/entity/user-session.entity.ts +73 -73
- package/src/module/user/entity/user.entity.ts +59 -59
- package/src/module/user/repository/role.repository.ts +96 -96
- package/src/module/user/repository/user-role-mapping.repository.ts +126 -126
- package/src/module/user/repository/user.repository.ts +50 -50
- package/src/module/user/repository/userSession.repository.ts +33 -33
- package/src/module/user/service/login.service.ts +284 -284
- package/src/module/user/service/role.service.ts +189 -189
- package/src/module/user/service/user-role-mapping.service.ts +98 -98
- package/src/module/user/service/user-session.service.ts +168 -168
- package/src/module/user/service/user.service.ts +365 -365
- package/src/module/user/user.module.ts +65 -65
- package/src/module/workflow/controller/action-category.controller.ts +54 -54
- package/src/module/workflow/controller/action-resource-mapping.controller.ts +23 -23
- package/src/module/workflow/controller/action-template-mapping.controller.ts +35 -35
- package/src/module/workflow/controller/action.controller.ts +111 -111
- package/src/module/workflow/controller/activity-log.controller.ts +55 -55
- package/src/module/workflow/controller/comm-template.controller.ts +43 -43
- package/src/module/workflow/controller/entity-modification.controller.ts +35 -35
- package/src/module/workflow/controller/form-master.controller.ts +43 -43
- package/src/module/workflow/controller/stage-group.controller.ts +48 -48
- package/src/module/workflow/controller/stage.controller.ts +50 -50
- package/src/module/workflow/controller/task.controller.ts +77 -77
- package/src/module/workflow/controller/workflow-list-master.controller.ts +44 -44
- package/src/module/workflow/controller/workflow-meta.controller.ts +80 -80
- package/src/module/workflow/controller/workflow.controller.ts +67 -67
- package/src/module/workflow/entity/action-category.entity.ts +38 -38
- package/src/module/workflow/entity/action-data.entity.ts +55 -55
- package/src/module/workflow/entity/action-resources-mapping.entity.ts +29 -29
- package/src/module/workflow/entity/action-template-mapping.entity.ts +17 -17
- package/src/module/workflow/entity/action.entity.ts +50 -50
- package/src/module/workflow/entity/activity-log.entity.ts +43 -43
- package/src/module/workflow/entity/comm-template.entity.ts +43 -43
- package/src/module/workflow/entity/entity-modification.entity.ts +38 -38
- package/src/module/workflow/entity/form.entity.ts +25 -25
- package/src/module/workflow/entity/stage-action-mapping.entity.ts +17 -17
- package/src/module/workflow/entity/stage-group.entity.ts +23 -23
- package/src/module/workflow/entity/stage-movement-data.entity.ts +38 -38
- package/src/module/workflow/entity/stage.entity.ts +20 -20
- package/src/module/workflow/entity/task-data.entity.ts +88 -88
- package/src/module/workflow/entity/template-attach-mapper.entity.ts +30 -30
- package/src/module/workflow/entity/workflow-data.entity.ts +11 -11
- package/src/module/workflow/entity/workflow-level-mapping.entity.ts +18 -18
- package/src/module/workflow/entity/workflow.entity.ts +20 -20
- package/src/module/workflow/repository/action-category.repository.ts +79 -79
- package/src/module/workflow/repository/action-data.repository.ts +333 -333
- package/src/module/workflow/repository/action.repository.ts +323 -323
- package/src/module/workflow/repository/activity-log.repository.ts +148 -148
- package/src/module/workflow/repository/comm-template.repository.ts +149 -149
- package/src/module/workflow/repository/form-master.repository.ts +59 -59
- package/src/module/workflow/repository/stage-group.repository.ts +176 -176
- package/src/module/workflow/repository/stage-movement.repository.ts +244 -244
- package/src/module/workflow/repository/stage.repository.ts +172 -172
- package/src/module/workflow/repository/task.repository.ts +127 -127
- package/src/module/workflow/repository/workflow.repository.ts +42 -42
- package/src/module/workflow/service/action-category.service.ts +33 -33
- package/src/module/workflow/service/action-data.service.ts +62 -62
- package/src/module/workflow/service/action-resources-mapping.service.ts +10 -10
- package/src/module/workflow/service/action-template-mapping.service.ts +106 -106
- package/src/module/workflow/service/action.service.ts +279 -279
- package/src/module/workflow/service/activity-log.service.ts +107 -107
- package/src/module/workflow/service/comm-template.service.ts +180 -180
- package/src/module/workflow/service/entity-modification.service.ts +67 -67
- package/src/module/workflow/service/form-master.service.ts +35 -35
- package/src/module/workflow/service/populate-workflow.service.ts +303 -303
- package/src/module/workflow/service/stage-action-mapping.service.ts +5 -5
- package/src/module/workflow/service/stage-group.service.ts +319 -319
- package/src/module/workflow/service/stage.service.ts +199 -199
- package/src/module/workflow/service/task.service.ts +560 -560
- package/src/module/workflow/service/workflow-list-master.service.ts +60 -60
- package/src/module/workflow/service/workflow-meta.service.ts +640 -640
- package/src/module/workflow/service/workflow.service.ts +205 -205
- package/src/module/workflow/workflow.module.ts +176 -176
- package/src/module/workflow-automation/controller/workflow-automation.controller.ts +21 -21
- package/src/module/workflow-automation/entity/workflow-automation-action.entity.ts +26 -26
- package/src/module/workflow-automation/entity/workflow-automation.entity.ts +35 -35
- package/src/module/workflow-automation/interface/action.decorator.ts +7 -7
- package/src/module/workflow-automation/interface/action.interface.ts +5 -5
- package/src/module/workflow-automation/service/action-registery.service.ts +35 -35
- package/src/module/workflow-automation/service/workflow-automation-engine.service.ts +214 -214
- package/src/module/workflow-automation/service/workflow-automation.service.ts +347 -347
- package/src/module/workflow-automation/workflow-automation.module.ts +34 -34
- package/src/resources/dev.properties.yaml +30 -30
- package/src/resources/local.properties.yaml +27 -27
- package/src/resources/properties.module.ts +12 -12
- package/src/resources/properties.yaml.ts +11 -11
- package/src/resources/uat.properties.yaml +31 -31
- package/src/table.config.ts +126 -126
- package/src/utils/dto/excel-data.dto.ts +14 -14
- package/src/utils/dto/excelsheet-data.dto.ts +5 -5
- package/src/utils/service/base64util.service.ts +18 -18
- package/src/utils/service/clockIDGenUtil.service.ts +21 -21
- package/src/utils/service/codeGenerator.service.ts +22 -22
- package/src/utils/service/dateUtil.service.ts +17 -17
- package/src/utils/service/encryptUtil.service.ts +97 -97
- package/src/utils/service/excel-helper.service.ts +72 -72
- package/src/utils/service/excelUtil.service.ts +15 -15
- package/src/utils/service/file-util.service.ts +11 -11
- package/src/utils/service/json-util.service.ts +23 -23
- package/src/utils/service/loggingUtil.service.ts +34 -34
- package/src/utils/service/reflection-helper.service.ts +62 -62
- package/src/utils/service/wbsCodeGen.service.ts +8 -8
- package/src/utils/utils.module.ts +25 -25
- package/tsconfig.build.json +4 -4
- package/tsconfig.json +24 -24
- package/.claude/settings.local.json +0 -26
- package/.idea/250218_nodejs_core.iml +0 -9
- package/.idea/codeStyles/Project.xml +0 -59
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/copilot.data.migration.agent.xml +0 -6
- package/.idea/copilot.data.migration.ask.xml +0 -6
- package/.idea/copilot.data.migration.ask2agent.xml +0 -6
- package/.idea/copilot.data.migration.edit.xml +0 -6
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/prettier.xml +0 -6
- package/.idea/vcs.xml +0 -6
- package/server.log +0 -850
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
2
|
-
import { InjectRepository } from '@nestjs/typeorm';
|
|
3
|
-
import { Otp } from '../entity/otp.entity';
|
|
4
|
-
import { Repository } from 'typeorm';
|
|
5
|
-
|
|
6
|
-
@Injectable()
|
|
7
|
-
export class OtpRepository {
|
|
8
|
-
constructor(
|
|
9
|
-
@InjectRepository(Otp) private readonly otpRepository: Repository<Otp>,
|
|
10
|
-
) {}
|
|
11
|
-
|
|
12
|
-
async save(otp: Otp) {
|
|
13
|
-
return await this.otpRepository.save(otp);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async findByOtpId(otpId: string) {
|
|
17
|
-
return await this.otpRepository.findOne({
|
|
18
|
-
where: {
|
|
19
|
-
otp_id: otpId,
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async update(id: number, otp: Otp) {
|
|
25
|
-
return await this.otpRepository.update(id, otp);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { InjectRepository } from '@nestjs/typeorm';
|
|
3
|
+
import { Otp } from '../entity/otp.entity';
|
|
4
|
+
import { Repository } from 'typeorm';
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class OtpRepository {
|
|
8
|
+
constructor(
|
|
9
|
+
@InjectRepository(Otp) private readonly otpRepository: Repository<Otp>,
|
|
10
|
+
) {}
|
|
11
|
+
|
|
12
|
+
async save(otp: Otp) {
|
|
13
|
+
return await this.otpRepository.save(otp);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async findByOtpId(otpId: string) {
|
|
17
|
+
return await this.otpRepository.findOne({
|
|
18
|
+
where: {
|
|
19
|
+
otp_id: otpId,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async update(id: number, otp: Otp) {
|
|
25
|
+
return await this.otpRepository.update(id, otp);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,127 +1,127 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
2
|
-
import { MailerService } from '@nestjs-modules/mailer';
|
|
3
|
-
import * as Handlebars from 'handlebars';
|
|
4
|
-
import { DataSource } from 'typeorm';
|
|
5
|
-
import { IcsMeetingService } from 'src/module/ics/service/ics.service';
|
|
6
|
-
|
|
7
|
-
@Injectable()
|
|
8
|
-
export class EmailService {
|
|
9
|
-
constructor(
|
|
10
|
-
private readonly mailerService: MailerService,
|
|
11
|
-
private readonly datasource: DataSource,
|
|
12
|
-
private readonly icsService: IcsMeetingService,
|
|
13
|
-
) {}
|
|
14
|
-
|
|
15
|
-
async sendEmail(
|
|
16
|
-
email: string,
|
|
17
|
-
subject: string,
|
|
18
|
-
context?: any,
|
|
19
|
-
icsPayload?: any,
|
|
20
|
-
) {
|
|
21
|
-
const template = await this.datasource
|
|
22
|
-
.getRepository('frm_wf_comm_template')
|
|
23
|
-
.findOne({ where: { code: 'OTP_TEMPLATE' } });
|
|
24
|
-
|
|
25
|
-
if (!template) return;
|
|
26
|
-
|
|
27
|
-
const compiled = Handlebars.compile(template.rich_text || '');
|
|
28
|
-
const htmlContent = compiled(context);
|
|
29
|
-
|
|
30
|
-
const attachments: any[] = [];
|
|
31
|
-
|
|
32
|
-
if (icsPayload) {
|
|
33
|
-
const icsBase64 = await this.icsService.generateIcs(icsPayload);
|
|
34
|
-
if (icsBase64) {
|
|
35
|
-
attachments.push({
|
|
36
|
-
filename: 'invite.ics',
|
|
37
|
-
content: icsBase64,
|
|
38
|
-
encoding: 'base64',
|
|
39
|
-
contentType: 'text/calendar; charset="utf-8"; method=REQUEST',
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// fire-and-forget // removed await
|
|
45
|
-
const result = this.mailerService
|
|
46
|
-
.sendMail({
|
|
47
|
-
to: email,
|
|
48
|
-
subject,
|
|
49
|
-
html: htmlContent,
|
|
50
|
-
attachments,
|
|
51
|
-
})
|
|
52
|
-
.then(() => {
|
|
53
|
-
console.log(`Email sent to ${email}`);
|
|
54
|
-
return;
|
|
55
|
-
})
|
|
56
|
-
.catch((err) => {
|
|
57
|
-
console.error(`Failed to send email to ${email}`, err);
|
|
58
|
-
// Optionally: push to a retry queue, Sentry, DB log, etc.
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
console.log(result); // Return immediately (parent doesn’t block)
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async sendEmailWithDynamicTemplate(
|
|
66
|
-
email: string,
|
|
67
|
-
subject: string,
|
|
68
|
-
templateCode: string,
|
|
69
|
-
cc?: string[],
|
|
70
|
-
bcc?: string[],
|
|
71
|
-
message?: string,
|
|
72
|
-
context?: any,
|
|
73
|
-
icsPayload?: any,
|
|
74
|
-
) {
|
|
75
|
-
// retrieve the rich_text from the database table frm_wf_comm_template for the given templateCode
|
|
76
|
-
const template = await this.datasource
|
|
77
|
-
.getRepository('frm_wf_comm_template')
|
|
78
|
-
.findOne({ where: { code: templateCode } });
|
|
79
|
-
|
|
80
|
-
if (!template) {
|
|
81
|
-
console.log(`Template with code ${templateCode} not found`);
|
|
82
|
-
return {
|
|
83
|
-
success: false,
|
|
84
|
-
message: `Template with code ${templateCode} not found`,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Compile the template string with Handlebars
|
|
89
|
-
const templateString = template.rich_text || '';
|
|
90
|
-
const compiled = Handlebars.compile(message || templateString);
|
|
91
|
-
const htmlContent = compiled(context);
|
|
92
|
-
|
|
93
|
-
// Attachments (ICS optional)
|
|
94
|
-
const attachments: any[] = [];
|
|
95
|
-
if (icsPayload) {
|
|
96
|
-
const icsBase64 = await this.icsService.generateIcs(icsPayload);
|
|
97
|
-
if (icsBase64) {
|
|
98
|
-
attachments.push({
|
|
99
|
-
filename: 'invite.ics',
|
|
100
|
-
content: icsBase64,
|
|
101
|
-
encoding: 'base64',
|
|
102
|
-
contentType: 'text/calendar; charset="utf-8"; method=REQUEST',
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const mailOptions: any = {
|
|
108
|
-
to: email,
|
|
109
|
-
subject,
|
|
110
|
-
html: htmlContent,
|
|
111
|
-
attachments,
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
if (cc && cc.length > 0) {
|
|
115
|
-
mailOptions.cc = cc;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (bcc && bcc.length > 0) {
|
|
119
|
-
mailOptions.bcc = bcc;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Send the email
|
|
123
|
-
await this.mailerService.sendMail(mailOptions);
|
|
124
|
-
|
|
125
|
-
return { success: true, message: 'Email sent successfully' };
|
|
126
|
-
}
|
|
127
|
-
}
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { MailerService } from '@nestjs-modules/mailer';
|
|
3
|
+
import * as Handlebars from 'handlebars';
|
|
4
|
+
import { DataSource } from 'typeorm';
|
|
5
|
+
import { IcsMeetingService } from 'src/module/ics/service/ics.service';
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class EmailService {
|
|
9
|
+
constructor(
|
|
10
|
+
private readonly mailerService: MailerService,
|
|
11
|
+
private readonly datasource: DataSource,
|
|
12
|
+
private readonly icsService: IcsMeetingService,
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
async sendEmail(
|
|
16
|
+
email: string,
|
|
17
|
+
subject: string,
|
|
18
|
+
context?: any,
|
|
19
|
+
icsPayload?: any,
|
|
20
|
+
) {
|
|
21
|
+
const template = await this.datasource
|
|
22
|
+
.getRepository('frm_wf_comm_template')
|
|
23
|
+
.findOne({ where: { code: 'OTP_TEMPLATE' } });
|
|
24
|
+
|
|
25
|
+
if (!template) return;
|
|
26
|
+
|
|
27
|
+
const compiled = Handlebars.compile(template.rich_text || '');
|
|
28
|
+
const htmlContent = compiled(context);
|
|
29
|
+
|
|
30
|
+
const attachments: any[] = [];
|
|
31
|
+
|
|
32
|
+
if (icsPayload) {
|
|
33
|
+
const icsBase64 = await this.icsService.generateIcs(icsPayload);
|
|
34
|
+
if (icsBase64) {
|
|
35
|
+
attachments.push({
|
|
36
|
+
filename: 'invite.ics',
|
|
37
|
+
content: icsBase64,
|
|
38
|
+
encoding: 'base64',
|
|
39
|
+
contentType: 'text/calendar; charset="utf-8"; method=REQUEST',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// fire-and-forget // removed await
|
|
45
|
+
const result = this.mailerService
|
|
46
|
+
.sendMail({
|
|
47
|
+
to: email,
|
|
48
|
+
subject,
|
|
49
|
+
html: htmlContent,
|
|
50
|
+
attachments,
|
|
51
|
+
})
|
|
52
|
+
.then(() => {
|
|
53
|
+
console.log(`Email sent to ${email}`);
|
|
54
|
+
return;
|
|
55
|
+
})
|
|
56
|
+
.catch((err) => {
|
|
57
|
+
console.error(`Failed to send email to ${email}`, err);
|
|
58
|
+
// Optionally: push to a retry queue, Sentry, DB log, etc.
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
console.log(result); // Return immediately (parent doesn’t block)
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async sendEmailWithDynamicTemplate(
|
|
66
|
+
email: string,
|
|
67
|
+
subject: string,
|
|
68
|
+
templateCode: string,
|
|
69
|
+
cc?: string[],
|
|
70
|
+
bcc?: string[],
|
|
71
|
+
message?: string,
|
|
72
|
+
context?: any,
|
|
73
|
+
icsPayload?: any,
|
|
74
|
+
) {
|
|
75
|
+
// retrieve the rich_text from the database table frm_wf_comm_template for the given templateCode
|
|
76
|
+
const template = await this.datasource
|
|
77
|
+
.getRepository('frm_wf_comm_template')
|
|
78
|
+
.findOne({ where: { code: templateCode } });
|
|
79
|
+
|
|
80
|
+
if (!template) {
|
|
81
|
+
console.log(`Template with code ${templateCode} not found`);
|
|
82
|
+
return {
|
|
83
|
+
success: false,
|
|
84
|
+
message: `Template with code ${templateCode} not found`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Compile the template string with Handlebars
|
|
89
|
+
const templateString = template.rich_text || '';
|
|
90
|
+
const compiled = Handlebars.compile(message || templateString);
|
|
91
|
+
const htmlContent = compiled(context);
|
|
92
|
+
|
|
93
|
+
// Attachments (ICS optional)
|
|
94
|
+
const attachments: any[] = [];
|
|
95
|
+
if (icsPayload) {
|
|
96
|
+
const icsBase64 = await this.icsService.generateIcs(icsPayload);
|
|
97
|
+
if (icsBase64) {
|
|
98
|
+
attachments.push({
|
|
99
|
+
filename: 'invite.ics',
|
|
100
|
+
content: icsBase64,
|
|
101
|
+
encoding: 'base64',
|
|
102
|
+
contentType: 'text/calendar; charset="utf-8"; method=REQUEST',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const mailOptions: any = {
|
|
108
|
+
to: email,
|
|
109
|
+
subject,
|
|
110
|
+
html: htmlContent,
|
|
111
|
+
attachments,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
if (cc && cc.length > 0) {
|
|
115
|
+
mailOptions.cc = cc;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (bcc && bcc.length > 0) {
|
|
119
|
+
mailOptions.bcc = bcc;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Send the email
|
|
123
|
+
await this.mailerService.sendMail(mailOptions);
|
|
124
|
+
|
|
125
|
+
return { success: true, message: 'Email sent successfully' };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -1,163 +1,163 @@
|
|
|
1
|
-
import { Inject, Injectable } from '@nestjs/common';
|
|
2
|
-
import { DataSource } from 'typeorm';
|
|
3
|
-
import { MediaDataService } from 'src/module/meta/service/media-data.service';
|
|
4
|
-
import * as admin from 'firebase-admin';
|
|
5
|
-
import axios from 'axios';
|
|
6
|
-
import { ConfigService } from '@nestjs/config';
|
|
7
|
-
|
|
8
|
-
@Injectable()
|
|
9
|
-
export class NotificationsService {
|
|
10
|
-
constructor(
|
|
11
|
-
private readonly dataSource: DataSource,
|
|
12
|
-
private readonly mediaDataService: MediaDataService,
|
|
13
|
-
private readonly configService: ConfigService,
|
|
14
|
-
@Inject('FIREBASE_ADMIN') private readonly firebaseAdmin: typeof admin,
|
|
15
|
-
) {}
|
|
16
|
-
|
|
17
|
-
private tokens: Map<string, string> = new Map(); // store in memory for now
|
|
18
|
-
|
|
19
|
-
async saveToken(userId: string | undefined, token: string) {
|
|
20
|
-
if (userId) {
|
|
21
|
-
this.tokens.set(userId, token);
|
|
22
|
-
}
|
|
23
|
-
return { success: true, token };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async sendToDevice(
|
|
27
|
-
token: string,
|
|
28
|
-
title: string,
|
|
29
|
-
body: string,
|
|
30
|
-
data?: Record<string, any>,
|
|
31
|
-
) {
|
|
32
|
-
// Utility to sanitize FCM data payload
|
|
33
|
-
const sanitizeFCMData = (
|
|
34
|
-
payload: Record<string, any>,
|
|
35
|
-
): Record<string, string> =>
|
|
36
|
-
Object.fromEntries(
|
|
37
|
-
Object.entries(payload).map(([k, v]) => {
|
|
38
|
-
if (v === null || v === undefined) return [k, '']; // fallback for null/undefined
|
|
39
|
-
if (typeof v === 'object') return [k, JSON.stringify(v)]; // preserve structure
|
|
40
|
-
return [k, String(v)]; // numbers, booleans, strings
|
|
41
|
-
}),
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
const message: admin.messaging.Message = {
|
|
45
|
-
token,
|
|
46
|
-
notification: { title, body }, // system notification
|
|
47
|
-
data: data ? sanitizeFCMData(data) : undefined,
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
return await this.firebaseAdmin.messaging().send(message);
|
|
52
|
-
} catch (error) {
|
|
53
|
-
console.error('Error sending FCM message:', error);
|
|
54
|
-
throw error;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Helper: send to a registered user by userId
|
|
59
|
-
async sendToUser(userId: string, title: string, body: string) {
|
|
60
|
-
const token = this.tokens.get(userId);
|
|
61
|
-
if (!token) return { error: 'No token found for user' };
|
|
62
|
-
|
|
63
|
-
return this.sendToDevice(token, title, body);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async getAllNotifications(
|
|
67
|
-
loggedInUser: any,
|
|
68
|
-
filterQuery?: {
|
|
69
|
-
is_read?: string;
|
|
70
|
-
},
|
|
71
|
-
) {
|
|
72
|
-
// if no filterQuery provided, return all notifications
|
|
73
|
-
const { id, level_id, level_type } = loggedInUser;
|
|
74
|
-
|
|
75
|
-
// Convert query param ("true"/"false") → SQL-friendly value (1/0)
|
|
76
|
-
let isReadFilter: number | undefined = undefined;
|
|
77
|
-
if (filterQuery && filterQuery.is_read !== undefined) {
|
|
78
|
-
const isReadBool = String(filterQuery.is_read).toLowerCase() === 'true';
|
|
79
|
-
isReadFilter = isReadBool ? 1 : 0;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Build query dynamically
|
|
83
|
-
let query = `
|
|
84
|
-
SELECT
|
|
85
|
-
n.*
|
|
86
|
-
FROM frm_notification n
|
|
87
|
-
WHERE n.user_id = ? AND n.level_id = ? AND n.level_type = ?
|
|
88
|
-
`;
|
|
89
|
-
|
|
90
|
-
const params: any[] = [id, level_id, level_type];
|
|
91
|
-
|
|
92
|
-
if (isReadFilter !== undefined) {
|
|
93
|
-
query += ` AND n.is_read = ?`;
|
|
94
|
-
params.push(isReadFilter);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
query += ` ORDER BY n.created_date DESC`;
|
|
98
|
-
|
|
99
|
-
const notifications = await this.dataSource.query(query, params);
|
|
100
|
-
|
|
101
|
-
// Profile media enrichment
|
|
102
|
-
const mediaCache = new Map();
|
|
103
|
-
for (const notification of notifications) {
|
|
104
|
-
// Ensure is_read is returned as boolean
|
|
105
|
-
notification.is_read = !!notification.is_read;
|
|
106
|
-
|
|
107
|
-
// if (notification.user_profile) {
|
|
108
|
-
// if (!mediaCache.has(notification.user_profile)) {
|
|
109
|
-
// const url = await this.mediaDataService.getMediaDownloadUrl(
|
|
110
|
-
// notification.user_profile,
|
|
111
|
-
// loggedInUser,
|
|
112
|
-
// );
|
|
113
|
-
// mediaCache.set(notification.user_profile, url);
|
|
114
|
-
// }
|
|
115
|
-
// notification.user_profile = mediaCache.get(notification.user_profile);
|
|
116
|
-
// } else {
|
|
117
|
-
// notification.user_profile = null;
|
|
118
|
-
// }
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
const baseUrl = this.configService.get<string>('REDIRECT_BE_URL');
|
|
122
|
-
|
|
123
|
-
// Prepare the query string
|
|
124
|
-
const queryParams = new URLSearchParams({
|
|
125
|
-
loggedInUser: JSON.stringify(loggedInUser),
|
|
126
|
-
}).toString();
|
|
127
|
-
|
|
128
|
-
// Make the GET request with query parameters
|
|
129
|
-
const response = await axios.get(
|
|
130
|
-
`${baseUrl}/users/profile-image-url/${notification?.user_id}?entity_type=USR&${queryParams}`,
|
|
131
|
-
{
|
|
132
|
-
headers: {
|
|
133
|
-
'Content-Type': 'application/json',
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
notification.user_name = response.data.name;
|
|
139
|
-
notification.user_profile = response.data.profile_image;
|
|
140
|
-
} catch (error) {
|
|
141
|
-
console.error('⚠️ Internal Entity API call failed:', error.message);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return notifications;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async markAllAsRead(loggedInUser: any) {
|
|
149
|
-
const { id, level_id, level_type } = loggedInUser;
|
|
150
|
-
|
|
151
|
-
const query = `
|
|
152
|
-
UPDATE frm_notification
|
|
153
|
-
SET is_read = 1
|
|
154
|
-
WHERE user_id = ? AND level_id = ? AND level_type = ? AND is_read = 0
|
|
155
|
-
`;
|
|
156
|
-
|
|
157
|
-
const params = [id, level_id, level_type];
|
|
158
|
-
|
|
159
|
-
const result = await this.dataSource.query(query, params);
|
|
160
|
-
|
|
161
|
-
return { success: true, affectedRows: result.affectedRows || 0 };
|
|
162
|
-
}
|
|
163
|
-
}
|
|
1
|
+
import { Inject, Injectable } from '@nestjs/common';
|
|
2
|
+
import { DataSource } from 'typeorm';
|
|
3
|
+
import { MediaDataService } from 'src/module/meta/service/media-data.service';
|
|
4
|
+
import * as admin from 'firebase-admin';
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
import { ConfigService } from '@nestjs/config';
|
|
7
|
+
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class NotificationsService {
|
|
10
|
+
constructor(
|
|
11
|
+
private readonly dataSource: DataSource,
|
|
12
|
+
private readonly mediaDataService: MediaDataService,
|
|
13
|
+
private readonly configService: ConfigService,
|
|
14
|
+
@Inject('FIREBASE_ADMIN') private readonly firebaseAdmin: typeof admin,
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
private tokens: Map<string, string> = new Map(); // store in memory for now
|
|
18
|
+
|
|
19
|
+
async saveToken(userId: string | undefined, token: string) {
|
|
20
|
+
if (userId) {
|
|
21
|
+
this.tokens.set(userId, token);
|
|
22
|
+
}
|
|
23
|
+
return { success: true, token };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async sendToDevice(
|
|
27
|
+
token: string,
|
|
28
|
+
title: string,
|
|
29
|
+
body: string,
|
|
30
|
+
data?: Record<string, any>,
|
|
31
|
+
) {
|
|
32
|
+
// Utility to sanitize FCM data payload
|
|
33
|
+
const sanitizeFCMData = (
|
|
34
|
+
payload: Record<string, any>,
|
|
35
|
+
): Record<string, string> =>
|
|
36
|
+
Object.fromEntries(
|
|
37
|
+
Object.entries(payload).map(([k, v]) => {
|
|
38
|
+
if (v === null || v === undefined) return [k, '']; // fallback for null/undefined
|
|
39
|
+
if (typeof v === 'object') return [k, JSON.stringify(v)]; // preserve structure
|
|
40
|
+
return [k, String(v)]; // numbers, booleans, strings
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const message: admin.messaging.Message = {
|
|
45
|
+
token,
|
|
46
|
+
notification: { title, body }, // system notification
|
|
47
|
+
data: data ? sanitizeFCMData(data) : undefined,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
return await this.firebaseAdmin.messaging().send(message);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('Error sending FCM message:', error);
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Helper: send to a registered user by userId
|
|
59
|
+
async sendToUser(userId: string, title: string, body: string) {
|
|
60
|
+
const token = this.tokens.get(userId);
|
|
61
|
+
if (!token) return { error: 'No token found for user' };
|
|
62
|
+
|
|
63
|
+
return this.sendToDevice(token, title, body);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async getAllNotifications(
|
|
67
|
+
loggedInUser: any,
|
|
68
|
+
filterQuery?: {
|
|
69
|
+
is_read?: string;
|
|
70
|
+
},
|
|
71
|
+
) {
|
|
72
|
+
// if no filterQuery provided, return all notifications
|
|
73
|
+
const { id, level_id, level_type } = loggedInUser;
|
|
74
|
+
|
|
75
|
+
// Convert query param ("true"/"false") → SQL-friendly value (1/0)
|
|
76
|
+
let isReadFilter: number | undefined = undefined;
|
|
77
|
+
if (filterQuery && filterQuery.is_read !== undefined) {
|
|
78
|
+
const isReadBool = String(filterQuery.is_read).toLowerCase() === 'true';
|
|
79
|
+
isReadFilter = isReadBool ? 1 : 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Build query dynamically
|
|
83
|
+
let query = `
|
|
84
|
+
SELECT
|
|
85
|
+
n.*
|
|
86
|
+
FROM frm_notification n
|
|
87
|
+
WHERE n.user_id = ? AND n.level_id = ? AND n.level_type = ?
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
const params: any[] = [id, level_id, level_type];
|
|
91
|
+
|
|
92
|
+
if (isReadFilter !== undefined) {
|
|
93
|
+
query += ` AND n.is_read = ?`;
|
|
94
|
+
params.push(isReadFilter);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
query += ` ORDER BY n.created_date DESC`;
|
|
98
|
+
|
|
99
|
+
const notifications = await this.dataSource.query(query, params);
|
|
100
|
+
|
|
101
|
+
// Profile media enrichment
|
|
102
|
+
const mediaCache = new Map();
|
|
103
|
+
for (const notification of notifications) {
|
|
104
|
+
// Ensure is_read is returned as boolean
|
|
105
|
+
notification.is_read = !!notification.is_read;
|
|
106
|
+
|
|
107
|
+
// if (notification.user_profile) {
|
|
108
|
+
// if (!mediaCache.has(notification.user_profile)) {
|
|
109
|
+
// const url = await this.mediaDataService.getMediaDownloadUrl(
|
|
110
|
+
// notification.user_profile,
|
|
111
|
+
// loggedInUser,
|
|
112
|
+
// );
|
|
113
|
+
// mediaCache.set(notification.user_profile, url);
|
|
114
|
+
// }
|
|
115
|
+
// notification.user_profile = mediaCache.get(notification.user_profile);
|
|
116
|
+
// } else {
|
|
117
|
+
// notification.user_profile = null;
|
|
118
|
+
// }
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
const baseUrl = this.configService.get<string>('REDIRECT_BE_URL');
|
|
122
|
+
|
|
123
|
+
// Prepare the query string
|
|
124
|
+
const queryParams = new URLSearchParams({
|
|
125
|
+
loggedInUser: JSON.stringify(loggedInUser),
|
|
126
|
+
}).toString();
|
|
127
|
+
|
|
128
|
+
// Make the GET request with query parameters
|
|
129
|
+
const response = await axios.get(
|
|
130
|
+
`${baseUrl}/users/profile-image-url/${notification?.user_id}?entity_type=USR&${queryParams}`,
|
|
131
|
+
{
|
|
132
|
+
headers: {
|
|
133
|
+
'Content-Type': 'application/json',
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
notification.user_name = response.data.name;
|
|
139
|
+
notification.user_profile = response.data.profile_image;
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.error('⚠️ Internal Entity API call failed:', error.message);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return notifications;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async markAllAsRead(loggedInUser: any) {
|
|
149
|
+
const { id, level_id, level_type } = loggedInUser;
|
|
150
|
+
|
|
151
|
+
const query = `
|
|
152
|
+
UPDATE frm_notification
|
|
153
|
+
SET is_read = 1
|
|
154
|
+
WHERE user_id = ? AND level_id = ? AND level_type = ? AND is_read = 0
|
|
155
|
+
`;
|
|
156
|
+
|
|
157
|
+
const params = [id, level_id, level_type];
|
|
158
|
+
|
|
159
|
+
const result = await this.dataSource.query(query, params);
|
|
160
|
+
|
|
161
|
+
return { success: true, affectedRows: result.affectedRows || 0 };
|
|
162
|
+
}
|
|
163
|
+
}
|