@comasoft/nestjs 0.2.25 → 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.
@@ -7,4 +7,3 @@ export * from './category.entity';
7
7
  export * from './role.entity';
8
8
  export * from './comment.entity';
9
9
  export * from './notification.entity';
10
- export * from './notification-recipient.entity';
@@ -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),t(require("./notification-recipient.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
- import { NotificationRecipient } from './notification-recipient.entity';
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
- sender: string;
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 t=this&&this.__decorate||function(t,e,o,i){var n,a=arguments.length,r=a<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,o,i);else for(var p=t.length-1;p>=0;p--)(n=t[p])&&(r=(a<3?n(r):a>3?n(e,o,r):n(e,o))||r);return a>3&&r&&Object.defineProperty(e,o,r),r},e=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.Notification=void 0;const o=require("typeorm"),i=require("../../enums.common"),n=require("./notification-recipient.entity");class Relations{}t([(0,o.OneToMany)(()=>n.NotificationRecipient,t=>t.notification),e("design:type",Array)],Relations.prototype,"recipients",void 0);let a=class Notification extends Relations{};exports.Notification=a,t([(0,o.PrimaryGeneratedColumn)({name:"id",primaryKeyConstraintName:"PK_notifications"}),e("design:type",Number)],a.prototype,"id",void 0),t([(0,o.Column)("varchar",{length:25}),e("design:type",String)],a.prototype,"type",void 0),t([(0,o.Column)("varchar",{length:50,nullable:!0}),e("design:type",String)],a.prototype,"batch_id",void 0),t([(0,o.Column)("varchar",{length:50}),e("design:type",String)],a.prototype,"template_key",void 0),t([(0,o.Column)("enum",{enum:i.NOTIFICATION_STATUS}),e("design:type",String)],a.prototype,"status",void 0),t([(0,o.Column)("varchar",{length:50,nullable:!0}),e("design:type",String)],a.prototype,"sender",void 0),t([(0,o.Column)("varchar",{length:100,nullable:!0}),e("design:type",String)],a.prototype,"title",void 0),t([(0,o.Column)("text",{nullable:!0}),e("design:type",String)],a.prototype,"content",void 0),t([(0,o.Column)("jsonb",{nullable:!0}),e("design:type",Object)],a.prototype,"meta",void 0),t([(0,o.Column)("timestamptz",{nullable:!0}),e("design:type",Date)],a.prototype,"scheduled_at",void 0),t([(0,o.Column)("timestamptz",{nullable:!0}),e("design:type",Date)],a.prototype,"sent_at",void 0),t([(0,o.CreateDateColumn)({type:"timestamptz"}),e("design:type",Date)],a.prototype,"created_at",void 0),t([(0,o.UpdateDateColumn)({type:"timestamptz"}),e("design:type",Date)],a.prototype,"updated_at",void 0),t([(0,o.DeleteDateColumn)({type:"timestamptz"}),e("design:type",Date)],a.prototype,"deleted_at",void 0),exports.Notification=a=t([(0,o.Entity)("notifications"),(0,o.Index)("IDX_notifications",["id"],{where:"deleted_at IS NULL"}),(0,o.Index)("IDX_notifications_status",["status"])],a);
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);
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,i,o){var r,p=arguments.length,a=p<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=(p<3?r(a):p>3?r(t,i,a):r(t,i))||a);return p>3&&a&&Object.defineProperty(t,i,a),a},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.FileThumbnailDto=exports.FileDto=void 0;const i=require("@nestjs/swagger"),o=require("class-transformer");class FileMetaDto{}e([(0,i.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"width",void 0),e([(0,i.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"height",void 0),e([(0,i.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"orientation",void 0),e([(0,i.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"duration",void 0),e([(0,i.ApiProperty)({type:String}),(0,o.Expose)(),t("design:type",String)],FileMetaDto.prototype,"encoding",void 0);class FileDto{}exports.FileDto=FileDto,e([(0,i.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileDto.prototype,"id",void 0),e([(0,i.ApiProperty)({type:String}),(0,o.Expose)(),t("design:type",String)],FileDto.prototype,"original_name",void 0),e([(0,i.ApiProperty)({type:String}),(0,o.Expose)(),t("design:type",String)],FileDto.prototype,"mime_type",void 0),e([(0,i.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileDto.prototype,"size",void 0),e([(0,i.ApiProperty)({type:String}),(0,o.Expose)(),(0,o.Transform)(({obj:e})=>{const t=process.env.CDN_URL||"";return"aws_legacy"===e.storage_type?`${t}/${e.file_name}`:`${t}/uploads/${e.target}/${e.path}/${e.file_name}`}),t("design:type",String)],FileDto.prototype,"full_url",void 0),e([(0,i.ApiProperty)({type:String}),(0,o.Expose)(),(0,o.Transform)(({obj:e})=>{var t;const i=process.env.CDN_URL||"";if("aws_legacy"===e.storage_type)return`${i}/${e.file_name}`;if(!1===e.has_thumbnail)return`${i}/uploads/${e.target}/${e.path}/${e.file_name}`;if(null===(t=e.mime_type)||void 0===t?void 0:t.startsWith("image/")){const t=e.file_name.replace(/\.[^.]+$/,".webp");return`${i}/thumbnails/${e.target}/${e.path}/sm/${t}`}}),t("design:type",String)],FileDto.prototype,"thumbnail_small",void 0),e([(0,i.ApiProperty)({type:String}),(0,o.Expose)(),(0,o.Transform)(({obj:e})=>{var t;const i=process.env.CDN_URL||"";if("aws_legacy"===e.storage_type)return`${i}/${e.file_name}`;if(!1===e.has_thumbnail)return`${i}/uploads/${e.target}/${e.path}/${e.file_name}`;if(null===(t=e.mime_type)||void 0===t?void 0:t.startsWith("image/")){const t=e.file_name.replace(/\.[^.]+$/,".webp");return`${i}/thumbnails/${e.target}/${e.path}/md/${t}`}}),t("design:type",String)],FileDto.prototype,"thumbnail_medium",void 0),e([(0,i.ApiProperty)({type:String}),(0,o.Expose)(),(0,o.Transform)(({obj:e})=>{var t;const i=process.env.CDN_URL||"";if("aws_legacy"===e.storage_type)return`${i}/${e.file_name}`;if(!1===e.has_thumbnail)return`${i}/uploads/${e.target}/${e.path}/${e.file_name}`;if(null===(t=e.mime_type)||void 0===t?void 0:t.startsWith("image/")){const t=e.file_name.replace(/\.[^.]+$/,".webp");return`${i}/thumbnails/${e.target}/${e.path}/lg/${t}`}}),t("design:type",String)],FileDto.prototype,"thumbnail_large",void 0),e([(0,i.ApiProperty)({type:FileMetaDto}),(0,o.Expose)(),(0,o.Type)(()=>FileMetaDto),(0,o.Transform)(({obj:e})=>e.meta),t("design:type",FileMetaDto)],FileDto.prototype,"meta",void 0);class FileThumbnailDto extends((0,i.PickType)(FileDto,["id","full_url","thumbnail_small","thumbnail_medium","thumbnail_large"])){}exports.FileThumbnailDto=FileThumbnailDto;
1
+ var e=this&&this.__decorate||function(e,t,r,o){var i,p=arguments.length,a=p<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,r):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,r,o);else for(var n=e.length-1;n>=0;n--)(i=e[n])&&(a=(p<3?i(a):p>3?i(t,r,a):i(t,r))||a);return p>3&&a&&Object.defineProperty(t,r,a),a},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.FileThumbnailDto=exports.FileDto=void 0;const r=require("@nestjs/swagger"),o=require("class-transformer");class FileMetaDto{}e([(0,r.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"width",void 0),e([(0,r.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"height",void 0),e([(0,r.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"orientation",void 0),e([(0,r.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileMetaDto.prototype,"duration",void 0),e([(0,r.ApiProperty)({type:String}),(0,o.Expose)(),t("design:type",String)],FileMetaDto.prototype,"encoding",void 0);class FileDto{}exports.FileDto=FileDto,e([(0,r.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileDto.prototype,"id",void 0),e([(0,r.ApiProperty)({type:String}),(0,o.Expose)(),t("design:type",String)],FileDto.prototype,"original_name",void 0),e([(0,r.ApiProperty)({type:String}),(0,o.Expose)(),t("design:type",String)],FileDto.prototype,"mime_type",void 0),e([(0,r.ApiProperty)({type:Number}),(0,o.Expose)(),t("design:type",Number)],FileDto.prototype,"size",void 0),e([(0,r.ApiProperty)({type:String}),(0,o.Expose)(),(0,o.Transform)(({obj:e})=>{const t=process.env.CDN_URL||"";return"remote"===e.storage_type?e.path:"aws_legacy"===e.storage_type?`${t}/${e.path}`:`${t}/uploads/${e.target}/${e.path}/${e.file_name}`}),t("design:type",String)],FileDto.prototype,"full_url",void 0),e([(0,r.ApiProperty)({type:String}),(0,o.Expose)(),(0,o.Transform)(({obj:e})=>{var t;const r=process.env.CDN_URL||"";if("remote"===e.storage_type)return e.path;if("aws_legacy"===e.storage_type)return`${r}/${e.path}`;if(!1===e.has_thumbnail)return`${r}/uploads/${e.target}/${e.path}/${e.file_name}`;if(null===(t=e.mime_type)||void 0===t?void 0:t.startsWith("image/")){const t=e.file_name.replace(/\.[^.]+$/,".webp");return`${r}/thumbnails/${e.target}/${e.path}/sm/${t}`}}),t("design:type",String)],FileDto.prototype,"thumbnail_small",void 0),e([(0,r.ApiProperty)({type:String}),(0,o.Expose)(),(0,o.Transform)(({obj:e})=>{var t;const r=process.env.CDN_URL||"";if("remote"===e.storage_type)return e.path;if("aws_legacy"===e.storage_type)return`${r}/${e.path}`;if(!1===e.has_thumbnail)return`${r}/uploads/${e.target}/${e.path}/${e.file_name}`;if(null===(t=e.mime_type)||void 0===t?void 0:t.startsWith("image/")){const t=e.file_name.replace(/\.[^.]+$/,".webp");return`${r}/thumbnails/${e.target}/${e.path}/md/${t}`}}),t("design:type",String)],FileDto.prototype,"thumbnail_medium",void 0),e([(0,r.ApiProperty)({type:String}),(0,o.Expose)(),(0,o.Transform)(({obj:e})=>{var t;const r=process.env.CDN_URL||"";if("remote"===e.storage_type)return e.path;if("aws_legacy"===e.storage_type)return`${r}/${e.path}`;if(!1===e.has_thumbnail)return`${r}/uploads/${e.target}/${e.path}/${e.file_name}`;if(null===(t=e.mime_type)||void 0===t?void 0:t.startsWith("image/")){const t=e.file_name.replace(/\.[^.]+$/,".webp");return`${r}/thumbnails/${e.target}/${e.path}/lg/${t}`}}),t("design:type",String)],FileDto.prototype,"thumbnail_large",void 0),e([(0,r.ApiProperty)({type:FileMetaDto}),(0,o.Expose)(),(0,o.Type)(()=>FileMetaDto),(0,o.Transform)(({obj:e})=>e.meta),t("design:type",FileMetaDto)],FileDto.prototype,"meta",void 0);class FileThumbnailDto extends((0,r.PickType)(FileDto,["id","full_url","thumbnail_small","thumbnail_medium","thumbnail_large"])){}exports.FileThumbnailDto=FileThumbnailDto;
@@ -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",
@@ -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"}(i||(exports.LIKE_TYPE=i={}));
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, NotificationService } from '../../notifications';
1
+ import { NotificationOptions, NotificationSendService } from '../../notifications';
2
2
  export declare class EventNotificationService {
3
- private readonly notificationService;
4
3
  private readonly notificationSendService;
5
- constructor(notificationService: NotificationService, notificationSendService: NotificationSendService);
6
- send(notification: NotificationOptions): Promise<void>;
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,a){var n,c=arguments.length,s=c<3?t:null===a?a=Object.getOwnPropertyDescriptor(t,i):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,i,a);else for(var l=e.length-1;l>=0;l--)(n=e[l])&&(s=(c<3?n(s):c>3?n(t,i,s):n(t,i))||s);return c>3&&s&&Object.defineProperty(t,i,s),s},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,a){return new(i||(i=Promise))(function(n,c){function fulfilled(e){try{step(a.next(e))}catch(e){c(e)}}function rejected(e){try{step(a.throw(e))}catch(e){c(e)}}function step(e){e.done?n(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((a=a.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.EventNotificationService=void 0;const a=require("@nestjs/common"),n=require("../../notifications");let c=class EventNotificationService{constructor(e,t){this.notificationService=e,this.notificationSendService=t}send(e){return i(this,void 0,void 0,function*(){if(null==e?void 0:e.web){yield this.notificationSendService.send({type:"web",recipients:e.web.recipients,template_key:e.web.template_key,variables:e.web.variables,meta:e.web.meta})}if(null==e?void 0:e.email){yield this.notificationService.create({type:"email",template_key:e.email.template_key,recipients:e.email.recipients,variables:e.email.variables});yield this.notificationSendService.send({type:"email",recipients:e.email.recipients,subject:e.email.subject,body:e.email.body,template_key:e.email.template_key,variables:e.email.variables})}if(null==e?void 0:e.kakao){yield this.notificationService.create({type:"kakao",template_key:e.kakao.template_key,recipients:e.kakao.recipients,variables:e.kakao.variables});yield this.notificationSendService.send({type:"kakao",recipients:e.kakao.recipients,template_key:e.kakao.template_key,variables:e.kakao.variables})}if(null==e?void 0:e.sms){yield this.notificationService.create({type:"sms",template_key:e.sms.template_key,recipients:e.sms.recipients,variables:e.sms.variables});yield this.notificationSendService.send({type:"sms",recipients:e.sms.recipients,content:e.sms.content,template_key:e.sms.template_key,variables:e.sms.variables})}if(null==e?void 0:e.slack){yield this.notificationService.create({type:"slack",template_key:e.slack.template_key,recipients:[{user_id:0,recipient:e.slack.channel}],variables:e.slack.variables});yield this.notificationSendService.send({type:"slack",channel:e.slack.channel,content:e.slack.content,template_key:e.slack.template_key,variables:e.slack.variables})}})}};exports.EventNotificationService=c,exports.EventNotificationService=c=e([(0,a.Injectable)(),t("design:paramtypes",[n.NotificationService,n.NotificationSendService])],c);
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);
@@ -1 +1 @@
1
- var e=this&&this.__decorate||function(e,t,r,i){var a,n=arguments.length,o=n<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,r,i);else for(var s=e.length-1;s>=0;s--)(a=e[s])&&(o=(n<3?a(o):n>3?a(t,r,o):a(t,r))||o);return n>3&&o&&Object.defineProperty(t,r,o),o},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},r=this&&this.__param||function(e,t){return function(r,i){t(r,i,e)}},i=this&&this.__awaiter||function(e,t,r,i){return new(r||(r=Promise))(function(a,n){function fulfilled(e){try{step(i.next(e))}catch(e){n(e)}}function rejected(e){try{step(i.throw(e))}catch(e){n(e)}}function step(e){e.done?a(e.value):function adopt(e){return e instanceof r?e:new r(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileService=void 0;const a=require("@nestjs/common"),n=require("typeorm"),o=require("../aws/aws-s3.service"),s=require("../database/entities"),d=require("../enums.common");let u=class FileService{constructor(e,t){this.dataSource=e,this.s3Service=t}findAll(e){return i(this,arguments,void 0,function*({target:e,target_id:t,group_number:r}){return this.dataSource.getRepository(s.File).find({where:{target:e,target_id:t,group_number:r},order:{sort:"ASC"}})})}createPending(e){return i(this,arguments,void 0,function*({target:e,user_id:t,files:r,manager:i,group_number:a}){const n=i?i.getRepository(s.File):this.dataSource.getRepository(s.File),o=yield n.save(r.map((r,i)=>{var n;return Object.assign(Object.assign({status:d.FILE_STATUS.PENDING,target:e,target_id:0,user_id:t},r),{sort:null!==(n=r.sort)&&void 0!==n?n:i+1,group_number:a})}));return o})}statusCompleted(e){return i(this,arguments,void 0,function*({target:e,target_id:t,user_id:r,file_ids:i,manager:a}){const o=a?a.getRepository(s.File):this.dataSource.getRepository(s.File);yield o.update({target:e,id:(0,n.In)(i)},{status:d.FILE_STATUS.COMPLETED,target_id:t})})}softDelete(e){return i(this,arguments,void 0,function*({target:e,target_id:t,user_id:r,delete_file_ids:i,manager:a}){const o=a?a.getRepository(s.File):this.dataSource.getRepository(s.File),u=yield o.find({where:{target:e,target_id:t,id:(0,n.In)(i)}});"samples"!==e&&(yield this.s3Service.deleteObjectsByKeys(u.map(e=>this.s3Service.getFileKey(e)))),yield o.update({id:(0,n.In)(u.map(e=>e.id))},{status:d.FILE_STATUS.DELETED,deleted_at:new Date,is_active:!1})})}softDeleteTarget(e){return i(this,arguments,void 0,function*({target:e,target_id:t,manager:r}){const i=r?r.getRepository(s.File):this.dataSource.getRepository(s.File),a=yield i.find({where:{target:e,target_id:t}});yield this.s3Service.deleteObjectsByKeys(a.map(e=>this.s3Service.getFileKey(e))),yield i.update({id:(0,n.In)(a.map(e=>e.id))},{status:d.FILE_STATUS.DELETED,deleted_at:new Date,is_active:!1})})}getHeroFileId(e){return i(this,arguments,void 0,function*({target:e,target_id:t,group_number:r,manager:i}){var a;const n=i?i.getRepository(s.File):this.dataSource.getRepository(s.File),o=yield n.findOne({where:{target:e,target_id:t,group_number:r},order:{sort:"ASC"},select:["id"]});return null!==(a=null==o?void 0:o.id)&&void 0!==a?a:null})}};exports.FileService=u,exports.FileService=u=e([(0,a.Injectable)(),r(1,(0,a.Inject)((0,a.forwardRef)(()=>o.S3Service))),t("design:paramtypes",[n.DataSource,o.S3Service])],u);
1
+ var e=this&&this.__decorate||function(e,t,r,i){var o,a=arguments.length,n=a<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,i);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(n=(a<3?o(n):a>3?o(t,r,n):o(t,r))||n);return a>3&&n&&Object.defineProperty(t,r,n),n},t=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},r=this&&this.__param||function(e,t){return function(r,i){t(r,i,e)}},i=this&&this.__awaiter||function(e,t,r,i){return new(r||(r=Promise))(function(o,a){function fulfilled(e){try{step(i.next(e))}catch(e){a(e)}}function rejected(e){try{step(i.throw(e))}catch(e){a(e)}}function step(e){e.done?o(e.value):function adopt(e){return e instanceof r?e:new r(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((i=i.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileService=void 0;const o=require("@nestjs/common"),a=require("typeorm"),n=require("../aws/aws-s3.service"),s=require("../database/entities"),d=require("../enums.common");let u=class FileService{constructor(e,t){this.dataSource=e,this.s3Service=t}findAll(e){return i(this,arguments,void 0,function*({target:e,target_id:t,group_number:r}){return this.dataSource.getRepository(s.File).find({where:{target:e,target_id:t,group_number:r},order:{sort:"ASC"}})})}createPending(e){return i(this,arguments,void 0,function*({target:e,user_id:t,files:r,manager:i,group_number:o}){const a=i?i.getRepository(s.File):this.dataSource.getRepository(s.File),n=yield a.save(r.map((r,i)=>{var a;return Object.assign(Object.assign({status:d.FILE_STATUS.PENDING,target:e,target_id:0,user_id:t},r),{sort:null!==(a=r.sort)&&void 0!==a?a:i+1,group_number:o})}));return n})}statusCompleted(e){return i(this,arguments,void 0,function*({target:e,target_id:t,user_id:r,file_ids:i,manager:o}){const n=o?o.getRepository(s.File):this.dataSource.getRepository(s.File);yield n.update({target:e,id:(0,a.In)(i)},{status:d.FILE_STATUS.COMPLETED,target_id:t})})}softDelete(e){return i(this,arguments,void 0,function*({target:e,target_id:t,user_id:r,delete_file_ids:i,manager:o}){const n=o?o.getRepository(s.File):this.dataSource.getRepository(s.File),u=yield n.find({where:{target:e,target_id:t,id:(0,a.In)(i)}});yield this.s3Service.deleteObjectsByKeys(u.map(e=>{if("aws"===e.storage_type)return this.s3Service.getFileKey(e)}).filter(Boolean)),yield n.update({id:(0,a.In)(u.map(e=>e.id))},{status:d.FILE_STATUS.DELETED,deleted_at:new Date,is_active:!1})})}softDeleteTarget(e){return i(this,arguments,void 0,function*({target:e,target_id:t,manager:r}){const i=r?r.getRepository(s.File):this.dataSource.getRepository(s.File),o=yield i.find({where:{target:e,target_id:t}});yield this.s3Service.deleteObjectsByKeys(o.map(e=>this.s3Service.getFileKey(e))),yield i.update({id:(0,a.In)(o.map(e=>e.id))},{status:d.FILE_STATUS.DELETED,deleted_at:new Date,is_active:!1})})}getHeroFileId(e){return i(this,arguments,void 0,function*({target:e,target_id:t,group_number:r,manager:i}){var o;const a=i?i.getRepository(s.File):this.dataSource.getRepository(s.File),n=yield a.findOne({where:{target:e,target_id:t,group_number:r},order:{sort:"ASC"},select:["id"]});return null!==(o=null==n?void 0:n.id)&&void 0!==o?o:null})}};exports.FileService=u,exports.FileService=u=e([(0,o.Injectable)(),r(1,(0,o.Inject)((0,o.forwardRef)(()=>n.S3Service))),t("design:paramtypes",[a.DataSource,n.S3Service])],u);
@@ -7,7 +7,25 @@ export interface NotificationRecipient {
7
7
  meta?: Record<string, any>;
8
8
  }
9
9
  export interface NotificationOptions {
10
- web?: {
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: 'web';
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,t,o){var r,c=arguments.length,n=c<3?i:null===o?o=Object.getOwnPropertyDescriptor(i,t):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,i,t,o);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(n=(c<3?r(n):c>3?r(i,t,n):r(i,t))||n);return c>3&&n&&Object.defineProperty(i,t,n),n};Object.defineProperty(exports,"__esModule",{value:!0}),exports.NotificationModule=void 0;const i=require("@nestjs/common"),t=require("@nestjs/typeorm"),o=require("../database/entities"),r=require("./services");let c=class NotificationModule{};exports.NotificationModule=c,exports.NotificationModule=c=e([(0,i.Global)(),(0,i.Module)({imports:[t.TypeOrmModule.forFeature([o.Config,o.Notification,o.NotificationRecipient])],providers:[r.NotificationService,r.NotificationSendService,r.MessageTemplateService,r.EmailService,r.KakaoService,r.SmsService,r.SlackService,r.WebNotificationService],exports:[r.NotificationSendService,r.NotificationService]})],c);
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);
@@ -5,4 +5,3 @@ export * from './email.service';
5
5
  export * from './kakao.service';
6
6
  export * from './sms.service';
7
7
  export * from './slack.service';
8
- export * from './web.service';
@@ -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),r(require("./web.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: 'web' | 'email' | 'sms' | 'slack' | 'kakao', templateKey: string): Promise<any>;
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
- import { WebNotificationService } from './web.service';
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 webNotificationService;
15
- private readonly messageTemplateService;
16
- private readonly dataSource;
17
- constructor(emailService: EmailService, smsService: SmsService, kakaoService: KakaoService, slackService: SlackService, webNotificationService: WebNotificationService, messageTemplateService: MessageTemplateService, dataSource: DataSource);
18
- send(payload: NotificationPayload): Promise<any[] | import("@aws-sdk/client-ses").SendEmailCommandOutput | import("resend").CreateEmailResponse | {
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 sendWeb;
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,r){var s,n=arguments.length,a=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,i):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,i,r);else for(var c=e.length-1;c>=0;c--)(s=e[c])&&(a=(n<3?s(a):n>3?s(t,i,a):s(t,i))||a);return n>3&&a&&Object.defineProperty(t,i,a),a},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,r){return new(i||(i=Promise))(function(s,n){function fulfilled(e){try{step(r.next(e))}catch(e){n(e)}}function rejected(e){try{step(r.throw(e))}catch(e){n(e)}}function step(e){e.done?s(e.value):function adopt(e){return e instanceof i?e:new i(function(t){t(e)})}(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.NotificationSendService=void 0;const r=require("@nestjs/common"),s=require("typeorm"),n=require("./email.service"),a=require("./kakao.service"),c=require("./message-template.service"),o=require("./slack.service"),l=require("./sms.service"),d=require("./web.service");let m=class NotificationSendService{constructor(e,t,i,r,s,n,a){this.emailService=e,this.smsService=t,this.kakaoService=i,this.slackService=r,this.webNotificationService=s,this.messageTemplateService=n,this.dataSource=a}send(e){return i(this,void 0,void 0,function*(){switch(e.type){case"web":return this.sendWeb(e);case"email":return this.sendEmail(e);case"sms":return this.sendSms(e);case"kakao":return this.sendKakao(e);case"slack":return this.sendSlack(e)}})}sendWeb(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r,s;if(e.template_key){const t=yield this.messageTemplateService.getTemplate("web",e.template_key);if(!t)throw new Error("Template not found "+e.template_key);const n=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(t,n).title||e.title||"",s=this.messageTemplateService.renderTemplate(t,n).content}else{if(!e.title||!e.content)throw new Error("title, content is required");r=e.title,s=e.content}t.push({recipient:i.recipient,user_id:i.user_id,title:r,content:s,variables:i.variables,meta:i.meta||e.meta})}return yield this.webNotificationService.send(Object.assign(Object.assign({},e),{recipients:t}))})}sendEmail(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r,s;if(e.template_key){const t=yield this.messageTemplateService.getTemplate("email",e.template_key);if(!t)throw new Error("Template not found "+e.template_key);const n=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(t,n).content,s=t.subject}else{if(!e.subject||!e.body)throw new Error("subject, body is required");r=e.body,s=e.subject}t.push({recipient:i.recipient,user_id:i.user_id,subject:s,text:r,variables:i.variables})}return yield this.emailService.send(t)})}sendSms(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r;if(e.template_key){const t=yield this.messageTemplateService.getTemplate("sms",e.template_key);if(!t)throw new Error("Template not found "+e.template_key);const s=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(t,s).content}else{if(!e.content)throw new Error("content is required");r=e.content}t.push({recipient:i.recipient,user_id:i.user_id,content:r,variables:i.variables})}return yield this.smsService.send(t)})}sendKakao(e){return i(this,void 0,void 0,function*(){const t=[];for(const i of e.recipients){let r;if(!e.template_key)throw new Error("template_key is required");const s=yield this.messageTemplateService.getTemplate("kakao",e.template_key);if(!s)throw new Error("Template not found "+e.template_key);const n=Object.assign(Object.assign({},e.variables),i.variables);r=this.messageTemplateService.renderTemplate(s,n).content,t.push({recipient:i.recipient,user_id:i.user_id,sender_key:s.sender_key,template_code:s.template_code,message:r})}return yield this.kakaoService.send(t)})}sendSlack(e){return i(this,void 0,void 0,function*(){let t;if(e.template_key){const i=yield this.messageTemplateService.getTemplate("slack",e.template_key);if(!i)throw new Error("Template not found "+e.template_key);t=this.messageTemplateService.renderTemplate(i,e.variables||{}).content}else{if(!e.content)throw new Error("content is required");t=e.content}return[yield this.slackService.send(e.channel,t)]})}};exports.NotificationSendService=m,exports.NotificationSendService=m=e([(0,r.Injectable)(),t("design:paramtypes",[n.EmailService,l.SmsService,a.KakaoService,o.SlackService,d.WebNotificationService,c.MessageTemplateService,s.DataSource])],m);
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, NotificationRecipient } from '../../database/entities';
2
+ import { Notification } from '../../database/entities';
4
3
  import { NOTIFICATION_STATUS } from '../../enums.common';
5
4
  export declare class NotificationService {
6
- private readonly notificationRepository;
7
- private readonly notificationRecipientRepository;
8
- private readonly configService;
9
- constructor(notificationRepository: Repository<Notification>, notificationRecipientRepository: Repository<NotificationRecipient>, configService: ConfigService);
10
- create({ type, template_key, title, content, recipients, variables, meta, }: {
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: string;
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
- notification: {
24
- type: string;
25
- template_key: string;
26
- title: string;
27
- content: string;
28
- sender: string;
29
- meta: Record<string, any>;
30
- status: NOTIFICATION_STATUS.PENDING;
31
- } & Notification;
32
- recipients: NotificationRecipient[];
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 getSenderByType;
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 e=this&&this.__decorate||function(e,t,i,n){var o,r=arguments.length,c=r<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 s=e.length-1;s>=0;s--)(o=e[s])&&(c=(r<3?o(c):r>3?o(t,i,c):o(t,i))||c);return r>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.__param||function(e,t){return function(i,n){t(i,n,e)}},n=this&&this.__awaiter||function(e,t,i,n){return new(i||(i=Promise))(function(o,r){function fulfilled(e){try{step(n.next(e))}catch(e){r(e)}}function rejected(e){try{step(n.throw(e))}catch(e){r(e)}}function step(e){e.done?o(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.NotificationService=void 0;const o=require("@nestjs/common"),r=require("@nestjs/config"),c=require("@nestjs/typeorm"),s=require("typeorm"),a=require("../../database/entities"),f=require("../../enums.common");let u=class NotificationService{constructor(e,t,i){this.notificationRepository=e,this.notificationRecipientRepository=t,this.configService=i}create(e){return n(this,arguments,void 0,function*({type:e,template_key:t,title:i,content:n,recipients:o,variables:r,meta:c}){const s=this.getSenderByType(e),a=yield this.notificationRepository.save({type:e,template_key:t,title:i,content:n,sender:s,meta:c,status:f.NOTIFICATION_STATUS.PENDING}),u=o.map(t=>this.notificationRecipientRepository.create({notification_id:a.id,type:e,user_id:t.user_id,recipient:t.recipient,title:i,content:n,meta:c,variables:t.variables,status:f.NOTIFICATION_STATUS.PENDING}));return yield this.notificationRecipientRepository.save(u),{notification:a,recipients:u}})}getSenderByType(e){switch(e){case"web":return"system";case"email":return this.configService.get("EMAIL_FROM")||"noreply@example.com";case"sms":return this.configService.get("SMS_FROM")||"";case"kakao":return this.configService.get("KAKAO_FROM")||"";case"slack":return this.configService.get("SLACK_CHANNEL")||"";default:return""}}findAll(){return n(this,void 0,void 0,function*(){return this.notificationRepository.find({relations:["recipients"],order:{created_at:"DESC"}})})}find(e){return n(this,void 0,void 0,function*(){return this.notificationRepository.findOne({where:{id:e},relations:["recipients"]})})}resend(e,t){return n(this,void 0,void 0,function*(){const i=yield this.notificationRecipientRepository.find({where:t?{notification_id:e,user_id:t}:{notification_id:e}});for(const e of i)e.status=f.NOTIFICATION_STATUS.PENDING,e.failed_at=null,e.reason_failed=null,yield this.notificationRecipientRepository.save(e);return i})}markAsRead(e,t){return n(this,void 0,void 0,function*(){const i=yield this.notificationRecipientRepository.findOne({where:{notification_id:e,user_id:t}});return i&&(i.status=f.NOTIFICATION_STATUS.READ,i.read_at=new Date,yield this.notificationRecipientRepository.save(i)),i})}};exports.NotificationService=u,exports.NotificationService=u=e([(0,o.Injectable)(),i(0,(0,c.InjectRepository)(a.Notification)),i(1,(0,c.InjectRepository)(a.NotificationRecipient)),t("design:paramtypes",[s.Repository,s.Repository,r.ConfigService])],u);
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comasoft/nestjs",
3
- "version": "0.2.25",
3
+ "version": "0.2.27",
4
4
  "description": "",
5
5
  "private": false,
6
6
  "exports": {