@comasoft/nestjs 0.2.26 → 0.2.27
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/dist/database/entities/index.d.ts +0 -1
- package/dist/database/entities/index.js +1 -1
- package/dist/database/entities/notification.entity.d.ts +13 -10
- package/dist/database/entities/notification.entity.js +1 -1
- package/dist/enums.common.d.ts +9 -0
- package/dist/enums.common.js +1 -1
- package/dist/events/services/event-notification.service.d.ts +6 -4
- package/dist/events/services/event-notification.service.js +1 -1
- package/dist/notifications/index.d.ts +46 -2
- package/dist/notifications/notification.module.js +1 -1
- package/dist/notifications/services/index.d.ts +0 -1
- package/dist/notifications/services/index.js +1 -1
- package/dist/notifications/services/message-template.service.d.ts +1 -1
- package/dist/notifications/services/notification-send.service.d.ts +35 -13
- package/dist/notifications/services/notification-send.service.js +1 -1
- package/dist/notifications/services/notification.service.d.ts +56 -23
- package/dist/notifications/services/notification.service.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,o)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),t=this&&this.__exportStar||function(t,r){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(r,i)||e(r,t,i)};Object.defineProperty(exports,"__esModule",{value:!0}),t(require("./logs-audit.entity"),exports),t(require("./logs-event.entity"),exports),t(require("./file.entity"),exports),t(require("./config.entity"),exports),t(require("./like.entity"),exports),t(require("./category.entity"),exports),t(require("./role.entity"),exports),t(require("./comment.entity"),exports),t(require("./notification.entity"),exports)
|
|
1
|
+
var e=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,o)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),t=this&&this.__exportStar||function(t,r){for(var i in t)"default"===i||Object.prototype.hasOwnProperty.call(r,i)||e(r,t,i)};Object.defineProperty(exports,"__esModule",{value:!0}),t(require("./logs-audit.entity"),exports),t(require("./logs-event.entity"),exports),t(require("./file.entity"),exports),t(require("./config.entity"),exports),t(require("./like.entity"),exports),t(require("./category.entity"),exports),t(require("./role.entity"),exports),t(require("./comment.entity"),exports),t(require("./notification.entity"),exports);
|
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
import { NOTIFICATION_STATUS } from '../../enums.common';
|
|
2
|
-
|
|
3
|
-
declare class Relations {
|
|
4
|
-
recipients: NotificationRecipient[];
|
|
5
|
-
}
|
|
6
|
-
export declare class Notification extends Relations {
|
|
1
|
+
import { NOTIFICATION_STATUS, NOTIFICATION_TYPE } from '../../enums.common';
|
|
2
|
+
export declare class Notification {
|
|
7
3
|
id: number;
|
|
8
|
-
type: string;
|
|
9
4
|
batch_id: string;
|
|
10
|
-
template_key: string;
|
|
11
5
|
status: NOTIFICATION_STATUS;
|
|
12
|
-
|
|
6
|
+
type: NOTIFICATION_TYPE;
|
|
7
|
+
user_id: number;
|
|
8
|
+
recipient: string;
|
|
9
|
+
template_key: string;
|
|
10
|
+
event_type: string;
|
|
11
|
+
event_id: number;
|
|
13
12
|
title: string;
|
|
14
13
|
content: string;
|
|
14
|
+
sender: string;
|
|
15
|
+
variables: Record<string, any>;
|
|
15
16
|
meta: Record<string, any>;
|
|
16
17
|
scheduled_at: Date;
|
|
17
18
|
sent_at: Date;
|
|
19
|
+
read_at: Date;
|
|
20
|
+
failed_at: Date;
|
|
21
|
+
reason_failed: string;
|
|
18
22
|
created_at: Date;
|
|
19
23
|
updated_at: Date;
|
|
20
24
|
deleted_at: Date;
|
|
21
25
|
}
|
|
22
|
-
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var e=this&&this.__decorate||function(e,t,n,o){var i,a=arguments.length,l=a<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,n,o);else for(var p=e.length-1;p>=0;p--)(i=e[p])&&(l=(a<3?i(l):a>3?i(t,n,l):i(t,n))||l);return a>3&&l&&Object.defineProperty(t,n,l),l},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.Notification=void 0;const n=require("typeorm"),o=require("../../enums.common");let i=class Notification{};exports.Notification=i,e([(0,n.PrimaryGeneratedColumn)({name:"id",primaryKeyConstraintName:"PK_notifications"}),t("design:type",Number)],i.prototype,"id",void 0),e([(0,n.Column)("varchar",{length:50,nullable:!0,comment:"배치 ID (1:N 발송 시 동일한 ID, null = 1:1 발송)"}),t("design:type",String)],i.prototype,"batch_id",void 0),e([(0,n.Column)("enum",{enum:o.NOTIFICATION_STATUS}),t("design:type",String)],i.prototype,"status",void 0),e([(0,n.Column)("varchar",{length:25,comment:Object.values(o.NOTIFICATION_TYPE).join(" | ")}),t("design:type",String)],i.prototype,"type",void 0),e([(0,n.Column)("int",{nullable:!0,comment:"사용자 ID (null = 배치 마스터)"}),t("design:type",Number)],i.prototype,"user_id",void 0),e([(0,n.Column)("varchar",{length:100,nullable:!0,comment:"수신자 주소 (email, phone 등)"}),t("design:type",String)],i.prototype,"recipient",void 0),e([(0,n.Column)("varchar",{length:50,comment:"템플릿 키"}),t("design:type",String)],i.prototype,"template_key",void 0),e([(0,n.Column)("varchar",{length:50,nullable:!0,comment:"이벤트 타입 (comment, pairing, notice 등)"}),t("design:type",String)],i.prototype,"event_type",void 0),e([(0,n.Column)("int",{nullable:!0,comment:"이벤트 대상 ID (post_id, schedule_id 등)"}),t("design:type",Number)],i.prototype,"event_id",void 0),e([(0,n.Column)("varchar",{length:100,nullable:!0,comment:"제목 (in_app, email에서 사용)"}),t("design:type",String)],i.prototype,"title",void 0),e([(0,n.Column)("text",{nullable:!0,comment:"내용"}),t("design:type",String)],i.prototype,"content",void 0),e([(0,n.Column)("varchar",{length:50,nullable:!0,comment:"발신자 (email: noreply@example.com, sms: 1234)"}),t("design:type",String)],i.prototype,"sender",void 0),e([(0,n.Column)("jsonb",{nullable:!0,comment:"템플릿 변수"}),t("design:type",Object)],i.prototype,"variables",void 0),e([(0,n.Column)("jsonb",{nullable:!0,comment:"추가 메타데이터 (url, image_url, 배치 정보 등)"}),t("design:type",Object)],i.prototype,"meta",void 0),e([(0,n.Column)("timestamptz",{nullable:!0,comment:"예약 발송 시각"}),t("design:type",Date)],i.prototype,"scheduled_at",void 0),e([(0,n.Column)("timestamptz",{nullable:!0,comment:"실제 발송 시각"}),t("design:type",Date)],i.prototype,"sent_at",void 0),e([(0,n.Column)("timestamptz",{nullable:!0,comment:"읽은 시각 (in_app만 사용)"}),t("design:type",Date)],i.prototype,"read_at",void 0),e([(0,n.Column)("timestamptz",{nullable:!0,comment:"발송 실패 시각"}),t("design:type",Date)],i.prototype,"failed_at",void 0),e([(0,n.Column)("varchar",{length:255,nullable:!0,comment:"실패 사유"}),t("design:type",String)],i.prototype,"reason_failed",void 0),e([(0,n.CreateDateColumn)({type:"timestamptz"}),t("design:type",Date)],i.prototype,"created_at",void 0),e([(0,n.UpdateDateColumn)({type:"timestamptz"}),t("design:type",Date)],i.prototype,"updated_at",void 0),e([(0,n.DeleteDateColumn)({type:"timestamptz"}),t("design:type",Date)],i.prototype,"deleted_at",void 0),exports.Notification=i=e([(0,n.Entity)("notifications"),(0,n.Index)("IDX_notifications",["id"],{where:"deleted_at IS NULL"}),(0,n.Index)("IDX_notifications_status",["status"]),(0,n.Index)("IDX_notifications_user_type",["user_id","type","created_at"]),(0,n.Index)("IDX_notifications_user_id",["user_id"],{where:"user_id IS NOT NULL"}),(0,n.Index)("IDX_notifications_batch",["batch_id"],{where:"batch_id IS NOT NULL"}),(0,n.Index)("IDX_notifications_event",["event_type","event_id"],{where:"event_type IS NOT NULL AND event_id IS NOT NULL"})],i);
|
package/dist/enums.common.d.ts
CHANGED
|
@@ -54,6 +54,15 @@ export declare enum NOTIFICATION_STATUS {
|
|
|
54
54
|
READ = "read",
|
|
55
55
|
FAILED = "failed"
|
|
56
56
|
}
|
|
57
|
+
export declare enum NOTIFICATION_TYPE {
|
|
58
|
+
IN_APP = "in_app",
|
|
59
|
+
WEB_PUSH = "web_push",
|
|
60
|
+
MOBILE_PUSH = "mobile_push",
|
|
61
|
+
EMAIL = "email",
|
|
62
|
+
SMS = "sms",
|
|
63
|
+
KAKAO = "kakao",
|
|
64
|
+
SLACK = "slack"
|
|
65
|
+
}
|
|
57
66
|
export declare enum LIKE_TYPE {
|
|
58
67
|
LIKE = "like",
|
|
59
68
|
DISLIKE = "dislike",
|
package/dist/enums.common.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,o,t,E,n,p,T,i;Object.defineProperty(exports,"__esModule",{value:!0}),exports.LIKE_TYPE=exports.NOTIFICATION_STATUS=exports.FILE_STORAGE_TYPE=exports.FILE_STATUS=exports.AUDIT_ACTION=exports.DEVICE_TYPE=exports.MIME_TYPE=exports.FILE_TYPE=void 0,function(e){e.IMAGE="IMAGE",e.VIDEO="VIDEO",e.DOCUMENT="DOCUMENT",e.AUDIO="AUDIO",e.OTHER="OTHER"}(e||(exports.FILE_TYPE=e={})),function(e){e.JPEG="image/jpeg",e.PNG="image/png",e.GIF="image/gif",e.PDF="application/pdf",e.DOC="application/msword",e.DOCX="application/vnd.openxmlformats-officedocument.wordprocessingml.document",e.XLS="application/vnd.ms-excel",e.XLSX="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",e.PPT="application/vnd.ms-powerpoint",e.PPTX="application/vnd.openxmlformats-officedocument.presentationml.presentation",e.TXT="text/plain",e.HTML="text/html",e.CSV="text/csv"}(o||(exports.MIME_TYPE=o={})),function(e){e.ANDROID="android",e.IOS="ios",e.PC="pc",e.MAC="mac",e.OTHER="other"}(t||(exports.DEVICE_TYPE=t={})),function(e){e.CREATE="create",e.READ="read",e.UPDATE="update",e.DELETE="delete",e.DOWNLOAD="download"}(E||(exports.AUDIT_ACTION=E={})),function(e){e.PENDING="pending",e.COMPLETED="completed",e.FAILED="failed",e.DELETED="deleted"}(n||(exports.FILE_STATUS=n={})),function(e){e.AWS="aws",e.AWS_LEGACY="aws_legacy",e.NCP="ncp",e.REMOTE="remote",e.LOCAL="local",e.OTHER="other"}(p||(exports.FILE_STORAGE_TYPE=p={})),function(e){e.PENDING="pending",e.SENT="sent",e.READ="read",e.FAILED="failed"}(T||(exports.NOTIFICATION_STATUS=T={})),function(e){e.LIKE="like",e.DISLIKE="dislike",e.NONE="none"}(
|
|
1
|
+
var e,o,t,E,n,p,T,i,I;Object.defineProperty(exports,"__esModule",{value:!0}),exports.LIKE_TYPE=exports.NOTIFICATION_TYPE=exports.NOTIFICATION_STATUS=exports.FILE_STORAGE_TYPE=exports.FILE_STATUS=exports.AUDIT_ACTION=exports.DEVICE_TYPE=exports.MIME_TYPE=exports.FILE_TYPE=void 0,function(e){e.IMAGE="IMAGE",e.VIDEO="VIDEO",e.DOCUMENT="DOCUMENT",e.AUDIO="AUDIO",e.OTHER="OTHER"}(e||(exports.FILE_TYPE=e={})),function(e){e.JPEG="image/jpeg",e.PNG="image/png",e.GIF="image/gif",e.PDF="application/pdf",e.DOC="application/msword",e.DOCX="application/vnd.openxmlformats-officedocument.wordprocessingml.document",e.XLS="application/vnd.ms-excel",e.XLSX="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",e.PPT="application/vnd.ms-powerpoint",e.PPTX="application/vnd.openxmlformats-officedocument.presentationml.presentation",e.TXT="text/plain",e.HTML="text/html",e.CSV="text/csv"}(o||(exports.MIME_TYPE=o={})),function(e){e.ANDROID="android",e.IOS="ios",e.PC="pc",e.MAC="mac",e.OTHER="other"}(t||(exports.DEVICE_TYPE=t={})),function(e){e.CREATE="create",e.READ="read",e.UPDATE="update",e.DELETE="delete",e.DOWNLOAD="download"}(E||(exports.AUDIT_ACTION=E={})),function(e){e.PENDING="pending",e.COMPLETED="completed",e.FAILED="failed",e.DELETED="deleted"}(n||(exports.FILE_STATUS=n={})),function(e){e.AWS="aws",e.AWS_LEGACY="aws_legacy",e.NCP="ncp",e.REMOTE="remote",e.LOCAL="local",e.OTHER="other"}(p||(exports.FILE_STORAGE_TYPE=p={})),function(e){e.PENDING="pending",e.SENT="sent",e.READ="read",e.FAILED="failed"}(T||(exports.NOTIFICATION_STATUS=T={})),function(e){e.IN_APP="in_app",e.WEB_PUSH="web_push",e.MOBILE_PUSH="mobile_push",e.EMAIL="email",e.SMS="sms",e.KAKAO="kakao",e.SLACK="slack"}(i||(exports.NOTIFICATION_TYPE=i={})),function(e){e.LIKE="like",e.DISLIKE="dislike",e.NONE="none"}(I||(exports.LIKE_TYPE=I={}));
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { NotificationOptions, NotificationSendService
|
|
1
|
+
import { NotificationOptions, NotificationSendService } from '../../notifications';
|
|
2
2
|
export declare class EventNotificationService {
|
|
3
|
-
private readonly notificationService;
|
|
4
3
|
private readonly notificationSendService;
|
|
5
|
-
constructor(
|
|
6
|
-
send(notification: NotificationOptions): Promise<
|
|
4
|
+
constructor(notificationSendService: NotificationSendService);
|
|
5
|
+
send(notification: NotificationOptions): Promise<{
|
|
6
|
+
batch_id: string;
|
|
7
|
+
}>;
|
|
8
|
+
private generateBatchId;
|
|
7
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__decorate||function(e,t,i,
|
|
1
|
+
var e=this&&this.__decorate||function(e,t,i,n){var a,s=arguments.length,c=s<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,t,i,n);else for(var l=e.length-1;l>=0;l--)(a=e[l])&&(c=(s<3?a(c):s>3?a(t,i,c):a(t,i))||c);return s>3&&c&&Object.defineProperty(t,i,c),c},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},i=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))(function(a,s){function fulfilled(e){try{step(n.next(e))}catch(e){s(e)}}function rejected(e){try{step(n.throw(e))}catch(e){s(e)}}function step(e){e.done?a(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.EventNotificationService=void 0;const n=require("@nestjs/common"),a=require("../../notifications");let s=class EventNotificationService{constructor(e){this.notificationSendService=e}send(e){return i(this,void 0,void 0,function*(){const t=this.generateBatchId();return(null==e?void 0:e.in_app)&&(yield this.notificationSendService.send({batch_id:t,channels:["in_app"],recipients:e.in_app.recipients,title:e.in_app.title,content:e.in_app.content,template_key:e.in_app.template_key,variables:e.in_app.variables,event_type:e.in_app.event_type,event_id:e.in_app.event_id,meta:e.in_app.meta})),(null==e?void 0:e.mobile_push)&&(yield this.notificationSendService.send({batch_id:t,channels:["mobile_push"],recipients:e.mobile_push.recipients,title:e.mobile_push.title,content:e.mobile_push.content,template_key:e.mobile_push.template_key,variables:e.mobile_push.variables,meta:e.mobile_push.meta})),(null==e?void 0:e.web_push)&&(yield this.notificationSendService.send({batch_id:t,channels:["web_push"],recipients:e.web_push.recipients,title:e.web_push.title,content:e.web_push.content,template_key:e.web_push.template_key,variables:e.web_push.variables,meta:e.web_push.meta})),(null==e?void 0:e.email)&&(yield this.notificationSendService.send({batch_id:t,channels:["email"],recipients:e.email.recipients,title:e.email.subject,content:e.email.body,template_key:e.email.template_key,variables:e.email.variables})),(null==e?void 0:e.kakao)&&(yield this.notificationSendService.send({batch_id:t,channels:["kakao"],recipients:e.kakao.recipients,template_key:e.kakao.template_key,variables:e.kakao.variables})),(null==e?void 0:e.sms)&&(yield this.notificationSendService.send({batch_id:t,channels:["sms"],recipients:e.sms.recipients,content:e.sms.content,template_key:e.sms.template_key,variables:e.sms.variables})),(null==e?void 0:e.slack)&&(yield this.notificationSendService.send({batch_id:t,channels:["slack"],recipients:[{user_id:0,recipient:e.slack.channel}],content:e.slack.content,template_key:e.slack.template_key,variables:e.slack.variables})),{batch_id:t}})}generateBatchId(){return`BATCH_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}};exports.EventNotificationService=s,exports.EventNotificationService=s=e([(0,n.Injectable)(),t("design:paramtypes",[a.NotificationSendService])],s);
|
|
@@ -7,7 +7,25 @@ export interface NotificationRecipient {
|
|
|
7
7
|
meta?: Record<string, any>;
|
|
8
8
|
}
|
|
9
9
|
export interface NotificationOptions {
|
|
10
|
-
|
|
10
|
+
in_app?: {
|
|
11
|
+
recipients: NotificationRecipient[];
|
|
12
|
+
title?: string;
|
|
13
|
+
content?: string;
|
|
14
|
+
template_key?: string;
|
|
15
|
+
variables?: Record<string, any>;
|
|
16
|
+
event_type?: string;
|
|
17
|
+
event_id?: number;
|
|
18
|
+
meta?: Record<string, any>;
|
|
19
|
+
};
|
|
20
|
+
mobile_push?: {
|
|
21
|
+
recipients: NotificationRecipient[];
|
|
22
|
+
title?: string;
|
|
23
|
+
content?: string;
|
|
24
|
+
template_key?: string;
|
|
25
|
+
variables?: Record<string, any>;
|
|
26
|
+
meta?: Record<string, any>;
|
|
27
|
+
};
|
|
28
|
+
web_push?: {
|
|
11
29
|
recipients: NotificationRecipient[];
|
|
12
30
|
title?: string;
|
|
13
31
|
content?: string;
|
|
@@ -41,7 +59,7 @@ export interface NotificationOptions {
|
|
|
41
59
|
};
|
|
42
60
|
}
|
|
43
61
|
export type NotificationPayload = {
|
|
44
|
-
type: '
|
|
62
|
+
type: 'in_app';
|
|
45
63
|
recipients: Array<{
|
|
46
64
|
recipient: string;
|
|
47
65
|
user_id: number;
|
|
@@ -54,6 +72,32 @@ export type NotificationPayload = {
|
|
|
54
72
|
content?: string;
|
|
55
73
|
template_key?: string;
|
|
56
74
|
variables?: Record<string, any>;
|
|
75
|
+
event_type?: string;
|
|
76
|
+
event_id?: number;
|
|
77
|
+
meta?: Record<string, any>;
|
|
78
|
+
} | {
|
|
79
|
+
type: 'mobile_push';
|
|
80
|
+
recipients: Array<{
|
|
81
|
+
recipient: string;
|
|
82
|
+
user_id: number;
|
|
83
|
+
variables?: Record<string, any>;
|
|
84
|
+
}>;
|
|
85
|
+
title?: string;
|
|
86
|
+
content?: string;
|
|
87
|
+
template_key?: string;
|
|
88
|
+
variables?: Record<string, any>;
|
|
89
|
+
meta?: Record<string, any>;
|
|
90
|
+
} | {
|
|
91
|
+
type: 'web_push';
|
|
92
|
+
recipients: Array<{
|
|
93
|
+
recipient: string;
|
|
94
|
+
user_id: number;
|
|
95
|
+
variables?: Record<string, any>;
|
|
96
|
+
}>;
|
|
97
|
+
title?: string;
|
|
98
|
+
content?: string;
|
|
99
|
+
template_key?: string;
|
|
100
|
+
variables?: Record<string, any>;
|
|
57
101
|
meta?: Record<string, any>;
|
|
58
102
|
} | {
|
|
59
103
|
type: 'email';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__decorate||function(e,i,
|
|
1
|
+
var e=this&&this.__decorate||function(e,t,i,o){var r,c=arguments.length,a=c<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,i,o);else for(var n=e.length-1;n>=0;n--)(r=e[n])&&(a=(c<3?r(a):c>3?r(t,i,a):r(t,i))||a);return c>3&&a&&Object.defineProperty(t,i,a),a};Object.defineProperty(exports,"__esModule",{value:!0}),exports.NotificationModule=void 0;const t=require("@nestjs/common"),i=require("@nestjs/typeorm"),o=require("../database/entities"),r=require("./services");let c=class NotificationModule{};exports.NotificationModule=c,exports.NotificationModule=c=e([(0,t.Global)(),(0,t.Module)({imports:[i.TypeOrmModule.forFeature([o.Config,o.Notification])],providers:[r.NotificationService,r.NotificationSendService,r.MessageTemplateService,r.EmailService,r.KakaoService,r.SmsService,r.SlackService],exports:[r.NotificationSendService,r.NotificationService]})],c);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__createBinding||(Object.create?function(e,r,t,i){void 0===i&&(i=t);var o=Object.getOwnPropertyDescriptor(r,t);o&&!("get"in o?!r.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,i,o)}:function(e,r,t,i){void 0===i&&(i=t),e[i]=r[t]}),r=this&&this.__exportStar||function(r,t){for(var i in r)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||e(t,r,i)};Object.defineProperty(exports,"__esModule",{value:!0}),r(require("./notification.service"),exports),r(require("./notification-send.service"),exports),r(require("./message-template.service"),exports),r(require("./email.service"),exports),r(require("./kakao.service"),exports),r(require("./sms.service"),exports),r(require("./slack.service"),exports)
|
|
1
|
+
var e=this&&this.__createBinding||(Object.create?function(e,r,t,i){void 0===i&&(i=t);var o=Object.getOwnPropertyDescriptor(r,t);o&&!("get"in o?!r.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,i,o)}:function(e,r,t,i){void 0===i&&(i=t),e[i]=r[t]}),r=this&&this.__exportStar||function(r,t){for(var i in r)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||e(t,r,i)};Object.defineProperty(exports,"__esModule",{value:!0}),r(require("./notification.service"),exports),r(require("./notification-send.service"),exports),r(require("./message-template.service"),exports),r(require("./email.service"),exports),r(require("./kakao.service"),exports),r(require("./sms.service"),exports),r(require("./slack.service"),exports);
|
|
@@ -3,7 +3,7 @@ import { Config } from '../../database/entities';
|
|
|
3
3
|
export declare class MessageTemplateService {
|
|
4
4
|
private configRepository;
|
|
5
5
|
constructor(configRepository: Repository<Config>);
|
|
6
|
-
getTemplate(type: '
|
|
6
|
+
getTemplate(type: 'in_app' | 'mobile_push' | 'web_push' | 'email' | 'sms' | 'slack' | 'kakao', templateKey: string): Promise<any>;
|
|
7
7
|
getTemplates(): Promise<Record<string, any>>;
|
|
8
8
|
updateTemplates(templates: any): Promise<void>;
|
|
9
9
|
renderTemplate(template: {
|
|
@@ -1,26 +1,48 @@
|
|
|
1
|
-
import { DataSource } from 'typeorm';
|
|
2
|
-
import { NotificationPayload } from '..';
|
|
3
1
|
import { EmailService } from './email.service';
|
|
4
2
|
import { KakaoService } from './kakao.service';
|
|
5
3
|
import { MessageTemplateService } from './message-template.service';
|
|
4
|
+
import { NotificationService } from './notification.service';
|
|
6
5
|
import { SlackService } from './slack.service';
|
|
7
6
|
import { SmsService } from './sms.service';
|
|
8
|
-
|
|
7
|
+
export interface SendNotificationDto {
|
|
8
|
+
batch_id?: string;
|
|
9
|
+
recipients: Array<{
|
|
10
|
+
user_id: number;
|
|
11
|
+
recipient?: string;
|
|
12
|
+
variables?: Record<string, any>;
|
|
13
|
+
}>;
|
|
14
|
+
channels: Array<'in_app' | 'mobile_push' | 'web_push' | 'email' | 'sms' | 'kakao' | 'slack'>;
|
|
15
|
+
template_key?: string;
|
|
16
|
+
title?: string;
|
|
17
|
+
content?: string;
|
|
18
|
+
variables?: Record<string, any>;
|
|
19
|
+
event_type?: string;
|
|
20
|
+
event_id?: number;
|
|
21
|
+
meta?: Record<string, any>;
|
|
22
|
+
}
|
|
9
23
|
export declare class NotificationSendService {
|
|
24
|
+
private readonly notificationService;
|
|
10
25
|
private readonly emailService;
|
|
11
26
|
private readonly smsService;
|
|
12
27
|
private readonly kakaoService;
|
|
13
28
|
private readonly slackService;
|
|
14
|
-
private readonly
|
|
15
|
-
private readonly
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
private readonly templateService;
|
|
30
|
+
private readonly logger;
|
|
31
|
+
constructor(notificationService: NotificationService, emailService: EmailService, smsService: SmsService, kakaoService: KakaoService, slackService: SlackService, templateService: MessageTemplateService);
|
|
32
|
+
send(dto: SendNotificationDto): Promise<any[] | {
|
|
33
|
+
batch_id: string;
|
|
34
|
+
total_count: number;
|
|
35
|
+
send_results: any[];
|
|
36
|
+
}>;
|
|
37
|
+
private sendSingle;
|
|
38
|
+
private sendBatch;
|
|
39
|
+
private sendToChannel;
|
|
40
|
+
private sendBatchToChannel;
|
|
41
|
+
resendBatch(batch_id: string, channel: string): Promise<{
|
|
19
42
|
success: boolean;
|
|
43
|
+
batch_id: string;
|
|
44
|
+
channel: string;
|
|
45
|
+
count: number;
|
|
20
46
|
}>;
|
|
21
|
-
private
|
|
22
|
-
private sendEmail;
|
|
23
|
-
private sendSms;
|
|
24
|
-
private sendKakao;
|
|
25
|
-
private sendSlack;
|
|
47
|
+
private renderTemplate;
|
|
26
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__decorate||function(e,t,i,
|
|
1
|
+
var e,t=this&&this.__decorate||function(e,t,i,n){var r,s=arguments.length,a=s<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,i,n);else for(var o=e.length-1;o>=0;o--)(r=e[o])&&(a=(s<3?r(a):s>3?r(t,i,a):r(t,i))||a);return s>3&&a&&Object.defineProperty(t,i,a),a},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))(function(r,s){function fulfilled(e){try{step(n.next(e))}catch(e){s(e)}}function rejected(e){try{step(n.throw(e))}catch(e){s(e)}}function step(e){e.done?r(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.NotificationSendService=void 0;const r=require("@nestjs/common"),s=require("../../enums.common"),a=require("./email.service"),o=require("./kakao.service"),c=require("./message-template.service"),l=require("./notification.service"),d=require("./slack.service"),h=require("./sms.service");let p=e=class NotificationSendService{constructor(t,i,n,s,a,o){this.notificationService=t,this.emailService=i,this.smsService=n,this.kakaoService=s,this.slackService=a,this.templateService=o,this.logger=new r.Logger(e.name)}send(e){return n(this,void 0,void 0,function*(){const{title:t,content:i}=yield this.renderTemplate(e);return 1===e.recipients.length?(this.logger.log(`1:1 알림 발송 시작: ${t}`),yield this.sendSingle(Object.assign(Object.assign({},e),{title:t,content:i}))):(this.logger.log(`1:N 배치 알림 발송 시작: ${t} (${e.recipients.length}명)`),yield this.sendBatch(Object.assign(Object.assign({},e),{title:t,content:i})))})}sendSingle(e){return n(this,void 0,void 0,function*(){const t=e.recipients[0],i=[];for(const n of e.channels){let r;try{"in_app"===n?(r=yield this.notificationService.createSingle({user_id:t.user_id,recipient:t.recipient,type:"in_app",template_key:e.template_key,event_type:e.event_type,event_id:e.event_id,title:e.title,content:e.content,variables:Object.assign(Object.assign({},e.variables),t.variables),meta:e.meta}),r.status=s.NOTIFICATION_STATUS.SENT,r.sent_at=new Date,yield this.notificationService.notificationRepository.save(r)):(r=yield this.notificationService.createSingle({user_id:null,recipient:t.recipient,type:n,template_key:e.template_key,event_type:e.event_type,event_id:e.event_id,title:e.title,content:e.content,variables:Object.assign(Object.assign({},e.variables),t.variables),meta:Object.assign(Object.assign({},e.meta),{target_user_id:t.user_id})}),yield this.sendToChannel(n,{recipient:t.recipient,title:e.title,content:e.content,meta:e.meta}),r.status=s.NOTIFICATION_STATUS.SENT,r.sent_at=new Date,yield this.notificationService.notificationRepository.save(r),this.logger.log(`${n} 발송 성공: user_id=${t.user_id}`)),i.push({channel:n,status:"success",notification:r})}catch(e){this.logger.error(`${n} 발송 실패: ${e.message}`,e.stack),r&&(r.status=s.NOTIFICATION_STATUS.FAILED,r.failed_at=new Date,r.reason_failed=e.message,yield this.notificationService.notificationRepository.save(r)),i.push({channel:n,status:"failed",error:e.message})}}return i})}sendBatch(e){return n(this,void 0,void 0,function*(){const{batch_id:t,total_count:i}=yield this.notificationService.createBatch({batch_id:e.batch_id,recipients:e.recipients,type:"in_app",template_key:e.template_key,event_type:e.event_type,event_id:e.event_id,title:e.title,content:e.content,variables:e.variables,meta:e.meta,channels:e.channels});this.logger.log(`배치 생성 완료: ${t} (${i}건)`);const n=e.channels.filter(e=>"in_app"!==e),r=[];for(const i of n)try{yield this.sendBatchToChannel(i,{recipients:e.recipients,title:e.title,content:e.content,meta:e.meta}),yield this.notificationService.notificationRepository.update({batch_id:t,type:i},{status:s.NOTIFICATION_STATUS.SENT,sent_at:new Date}),r.push({channel:i,status:"sent"}),this.logger.log(`${i} 배치 발송 성공: ${e.recipients.length}명`)}catch(e){this.logger.error(`${i} 배치 발송 실패: ${e.message}`,e.stack),yield this.notificationService.notificationRepository.update({batch_id:t,type:i},{status:s.NOTIFICATION_STATUS.FAILED,failed_at:new Date,reason_failed:e.message}),r.push({channel:i,status:"failed",error:e.message})}return{batch_id:t,total_count:i,send_results:r}})}sendToChannel(e,t){return n(this,void 0,void 0,function*(){var i,n,r,s,a;switch(e){case"mobile_push":throw this.logger.warn("mobile_push 채널은 아직 구현되지 않았습니다"),new Error("mobile_push not implemented yet");case"web_push":throw this.logger.warn("web_push 채널은 아직 구현되지 않았습니다"),new Error("web_push not implemented yet");case"email":return yield this.emailService.send([{recipient:t.recipient,user_id:null===(i=t.meta)||void 0===i?void 0:i.target_user_id,subject:t.title,text:t.content}]);case"sms":return yield this.smsService.send([{recipient:t.recipient,user_id:null===(n=t.meta)||void 0===n?void 0:n.target_user_id,message:t.content}]);case"kakao":return yield this.kakaoService.send([{recipient:t.recipient,user_id:null===(r=t.meta)||void 0===r?void 0:r.target_user_id,sender_key:null===(s=t.meta)||void 0===s?void 0:s.sender_key,template_code:null===(a=t.meta)||void 0===a?void 0:a.template_code,message:t.content}]);case"slack":return yield this.slackService.send(t.recipient,t.content);default:throw new Error(`Unknown channel: ${e}`)}})}sendBatchToChannel(e,t){return n(this,void 0,void 0,function*(){switch(e){case"mobile_push":throw this.logger.warn("mobile_push 배치 발송은 아직 구현되지 않았습니다"),new Error("mobile_push batch sending not implemented yet");case"web_push":throw this.logger.warn("web_push 배치 발송은 아직 구현되지 않았습니다"),new Error("web_push batch sending not implemented yet");case"email":{const e=t.recipients.map(e=>({recipient:e.recipient,user_id:e.user_id,subject:t.title,text:t.content})).filter(e=>e.recipient);if(0===e.length)throw new Error("No email addresses provided");return yield this.emailService.send(e)}case"sms":{const e=t.recipients.map(e=>({recipient:e.recipient,user_id:e.user_id,message:t.content})).filter(e=>e.recipient);if(0===e.length)throw new Error("No phone numbers provided");return yield this.smsService.send(e)}case"kakao":{const e=t.recipients.map(e=>{var i,n;return{recipient:e.recipient,user_id:e.user_id,sender_key:null===(i=t.meta)||void 0===i?void 0:i.sender_key,template_code:null===(n=t.meta)||void 0===n?void 0:n.template_code,message:t.content}}).filter(e=>e.recipient);if(0===e.length)throw new Error("No kakao recipients provided");return yield this.kakaoService.send(e)}default:throw new Error(`Batch sending not supported for ${e}`)}})}resendBatch(e,t){return n(this,void 0,void 0,function*(){this.logger.log(`배치 재발송 시작: ${e}, ${t}`);const i=yield this.notificationService.notificationRepository.find({where:{batch_id:e,type:t}});if(0===i.length)throw new Error(`Batch records not found: ${e}, ${t}`);const n=i.map(e=>({user_id:e.user_id,recipient:e.recipient,variables:e.variables})),r=i[0];try{return yield this.sendBatchToChannel(t,{recipients:n,title:r.title,content:r.content,meta:r.meta}),yield this.notificationService.notificationRepository.update({batch_id:e,type:t},{status:s.NOTIFICATION_STATUS.SENT,sent_at:new Date}),this.logger.log(`배치 재발송 성공: ${e}`),{success:!0,batch_id:e,channel:t,count:n.length}}catch(i){throw this.logger.error(`배치 재발송 실패: ${i.message}`,i.stack),yield this.notificationService.notificationRepository.update({batch_id:e,type:t},{status:s.NOTIFICATION_STATUS.FAILED,failed_at:new Date,reason_failed:i.message}),i}})}renderTemplate(e){return n(this,void 0,void 0,function*(){var t;if(e.template_key){const i=e.channels[0],n=yield this.templateService.getTemplate(i,e.template_key);if(!n)throw new Error(`Template not found: ${e.template_key} for ${i}`);const r=Object.assign(Object.assign({},e.variables),(null===(t=e.recipients[0])||void 0===t?void 0:t.variables)||{}),s=this.templateService.renderTemplate(n,r);return{title:s.title||e.title||"",content:s.content}}if(!e.title||!e.content)throw new Error("title and content are required when template_key is not provided");return{title:e.title,content:e.content}})}};exports.NotificationSendService=p,exports.NotificationSendService=p=e=t([(0,r.Injectable)(),i("design:paramtypes",[l.NotificationService,a.EmailService,h.SmsService,o.KakaoService,d.SlackService,c.MessageTemplateService])],p);
|
|
@@ -1,39 +1,72 @@
|
|
|
1
|
-
import { ConfigService } from '@nestjs/config';
|
|
2
1
|
import { Repository } from 'typeorm';
|
|
3
|
-
import { Notification
|
|
2
|
+
import { Notification } from '../../database/entities';
|
|
4
3
|
import { NOTIFICATION_STATUS } from '../../enums.common';
|
|
5
4
|
export declare class NotificationService {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
readonly notificationRepository: Repository<Notification>;
|
|
6
|
+
constructor(notificationRepository: Repository<Notification>);
|
|
7
|
+
createSingle({ user_id, recipient, type, template_key, event_type, event_id, title, content, variables, meta, }: {
|
|
8
|
+
user_id: number;
|
|
9
|
+
recipient?: string;
|
|
11
10
|
type: string;
|
|
12
11
|
template_key: string;
|
|
12
|
+
event_type?: string;
|
|
13
|
+
event_id?: number;
|
|
13
14
|
title?: string;
|
|
14
15
|
content?: string;
|
|
16
|
+
variables?: Record<string, any>;
|
|
17
|
+
meta?: Record<string, any>;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
user_id: number;
|
|
20
|
+
recipient: string;
|
|
21
|
+
type: any;
|
|
22
|
+
template_key: string;
|
|
23
|
+
event_type: any;
|
|
24
|
+
event_id: number;
|
|
25
|
+
title: string;
|
|
26
|
+
content: string;
|
|
27
|
+
variables: Record<string, any>;
|
|
28
|
+
meta: Record<string, any>;
|
|
29
|
+
status: NOTIFICATION_STATUS.PENDING;
|
|
30
|
+
} & Notification>;
|
|
31
|
+
createBatch({ batch_id, recipients, type, template_key, event_type, event_id, title, content, variables, meta, channels, }: {
|
|
32
|
+
batch_id?: string;
|
|
15
33
|
recipients: Array<{
|
|
16
34
|
user_id: number;
|
|
17
|
-
recipient
|
|
35
|
+
recipient?: string;
|
|
18
36
|
variables?: Record<string, any>;
|
|
19
37
|
}>;
|
|
38
|
+
type: string;
|
|
39
|
+
template_key: string;
|
|
40
|
+
event_type?: string;
|
|
41
|
+
event_id?: number;
|
|
42
|
+
title: string;
|
|
43
|
+
content: string;
|
|
20
44
|
variables?: Record<string, any>;
|
|
21
45
|
meta?: Record<string, any>;
|
|
46
|
+
channels?: string[];
|
|
22
47
|
}): Promise<{
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
48
|
+
batch_id: string;
|
|
49
|
+
total_count: number;
|
|
50
|
+
notifications: any[];
|
|
51
|
+
}>;
|
|
52
|
+
findByUser(user_id: number, options?: {
|
|
53
|
+
limit?: number;
|
|
54
|
+
offset?: number;
|
|
55
|
+
unread_only?: boolean;
|
|
56
|
+
}): Promise<Notification[]>;
|
|
57
|
+
countUnread(user_id: number): Promise<number>;
|
|
58
|
+
markAsRead(id: number, user_id: number): Promise<import("typeorm").UpdateResult>;
|
|
59
|
+
markAllAsRead(user_id: number): Promise<import("typeorm").UpdateResult>;
|
|
60
|
+
delete(id: number, user_id: number): Promise<import("typeorm").UpdateResult>;
|
|
61
|
+
markBatchAsSent(batch_id: string, channel: string): Promise<import("typeorm").UpdateResult>;
|
|
62
|
+
markBatchAsFailed(batch_id: string, channel: string, reason: string): Promise<import("typeorm").UpdateResult>;
|
|
63
|
+
findBatchMaster(batch_id: string, channel: string): Promise<Notification>;
|
|
64
|
+
findBatchRecipients(batch_id: string): Promise<Notification[]>;
|
|
65
|
+
getBatchStats(batch_id: string): Promise<{
|
|
66
|
+
total: number;
|
|
67
|
+
read: number;
|
|
68
|
+
unread: number;
|
|
69
|
+
read_rate: number;
|
|
33
70
|
}>;
|
|
34
|
-
private
|
|
35
|
-
findAll(): Promise<Notification[]>;
|
|
36
|
-
find(id: number): Promise<Notification>;
|
|
37
|
-
resend(notification_id: number, user_id?: number): Promise<NotificationRecipient[]>;
|
|
38
|
-
markAsRead(notification_id: number, user_id: number): Promise<NotificationRecipient>;
|
|
71
|
+
private generateBatchId;
|
|
39
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var t=this&&this.__decorate||function(t,e,i,n){var r,a=arguments.length,o=a<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(t,e,i,n);else for(var s=t.length-1;s>=0;s--)(r=t[s])&&(o=(a<3?r(o):a>3?r(e,i,o):r(e,i))||o);return a>3&&o&&Object.defineProperty(e,i,o),o},e=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)},i=this&&this.__param||function(t,e){return function(i,n){e(i,n,t)}},n=this&&this.__awaiter||function(t,e,i,n){return new(i||(i=Promise))(function(r,a){function fulfilled(t){try{step(n.next(t))}catch(t){a(t)}}function rejected(t){try{step(n.throw(t))}catch(t){a(t)}}function step(t){t.done?r(t.value):function adopt(t){return t instanceof i?t:new i(function(e){e(t)})}(t.value).then(fulfilled,rejected)}step((n=n.apply(t,e||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.NotificationService=void 0;const r=require("@nestjs/common"),a=require("@nestjs/typeorm"),o=require("typeorm"),s=require("../../database/entities"),d=require("../../enums.common");let c=class NotificationService{constructor(t){this.notificationRepository=t}createSingle(t){return n(this,arguments,void 0,function*({user_id:t,recipient:e,type:i,template_key:n,event_type:r,event_id:a,title:o,content:s,variables:c,meta:u}){return yield this.notificationRepository.save({user_id:t,recipient:e,type:i,template_key:n,event_type:r,event_id:a,title:o,content:s,variables:c,meta:u,status:d.NOTIFICATION_STATUS.PENDING})})}createBatch(t){return n(this,arguments,void 0,function*({batch_id:t,recipients:e,type:i,template_key:n,event_type:r,event_id:a,title:o,content:s,variables:c,meta:u,channels:p=["in_app","mobile_push"]}){const l=t||this.generateBatchId(),_=[];for(const t of p){const i=e.map(e=>({user_id:e.user_id,recipient:e.recipient,type:t,template_key:n,event_type:r,event_id:a,title:o,content:s,variables:Object.assign(Object.assign({},c),e.variables),meta:u,batch_id:l,status:"in_app"===t?d.NOTIFICATION_STATUS.SENT:d.NOTIFICATION_STATUS.PENDING,sent_at:"in_app"===t?new Date:null}));_.push(...i)}const f=yield this.notificationRepository.save(_);return{batch_id:l,total_count:f.length,notifications:f}})}findByUser(t,e){return n(this,void 0,void 0,function*(){const i=this.notificationRepository.createQueryBuilder("n").where("n.user_id = :user_id",{user_id:t}).andWhere("n.type = :type",{type:"in_app"}).andWhere("n.deleted_at IS NULL");return(null==e?void 0:e.unread_only)&&i.andWhere("n.read_at IS NULL"),i.orderBy("n.created_at","DESC").limit((null==e?void 0:e.limit)||20).offset((null==e?void 0:e.offset)||0),yield i.getMany()})}countUnread(t){return n(this,void 0,void 0,function*(){return yield this.notificationRepository.count({where:{user_id:t,type:"in_app",read_at:(0,o.IsNull)(),deleted_at:(0,o.IsNull)()}})})}markAsRead(t,e){return n(this,void 0,void 0,function*(){return yield this.notificationRepository.update({id:t,user_id:e,type:"in_app"},{status:d.NOTIFICATION_STATUS.READ,read_at:new Date})})}markAllAsRead(t){return n(this,void 0,void 0,function*(){return yield this.notificationRepository.update({user_id:t,type:"in_app",read_at:(0,o.IsNull)()},{status:d.NOTIFICATION_STATUS.READ,read_at:new Date})})}delete(t,e){return n(this,void 0,void 0,function*(){return yield this.notificationRepository.softDelete({id:t,user_id:e,type:"in_app"})})}markBatchAsSent(t,e){return n(this,void 0,void 0,function*(){return yield this.notificationRepository.update({batch_id:t,type:e,user_id:(0,o.IsNull)()},{status:d.NOTIFICATION_STATUS.SENT,sent_at:new Date})})}markBatchAsFailed(t,e,i){return n(this,void 0,void 0,function*(){return yield this.notificationRepository.update({batch_id:t,type:e,user_id:(0,o.IsNull)()},{status:d.NOTIFICATION_STATUS.FAILED,failed_at:new Date,reason_failed:i})})}findBatchMaster(t,e){return n(this,void 0,void 0,function*(){return yield this.notificationRepository.findOne({where:{batch_id:t,type:e,user_id:(0,o.IsNull)()}})})}findBatchRecipients(t){return n(this,void 0,void 0,function*(){return yield this.notificationRepository.find({where:{batch_id:t,type:"in_app",user_id:(0,o.Not)((0,o.IsNull)())},order:{created_at:"DESC"}})})}getBatchStats(t){return n(this,void 0,void 0,function*(){const e=yield this.notificationRepository.createQueryBuilder("n").select("COUNT(*)","total").addSelect("COUNT(n.read_at)","read").addSelect("COUNT(*) - COUNT(n.read_at)","unread").addSelect("ROUND(COUNT(n.read_at) * 100.0 / COUNT(*), 2)","read_rate").where("n.batch_id = :batch_id",{batch_id:t}).andWhere("n.type = :type",{type:"in_app"}).andWhere("n.user_id IS NOT NULL").getRawOne();return{total:parseInt(e.total),read:parseInt(e.read),unread:parseInt(e.unread),read_rate:parseFloat(e.read_rate)}})}generateBatchId(){return`BATCH_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}};exports.NotificationService=c,exports.NotificationService=c=t([(0,r.Injectable)(),i(0,(0,a.InjectRepository)(s.Notification)),e("design:paramtypes",[o.Repository])],c);
|