1- import { Notification } from 'hawk-worker-sender/types/template-variables' ;
1+ import { Notification , TemplateEventData } from 'hawk-worker-sender/types/template-variables' ;
2+ import {
3+ ProjectDBScheme ,
4+ WorkspaceDBScheme ,
5+ UserDBScheme ,
6+ DecodedGroupedEvent ,
7+ PlanDBScheme ,
8+ } from '@hawk.so/types' ;
29import { WebhookDelivery } from '../../types/template' ;
310
411/**
5- * Converts ObjectId (or any BSON value) to string, passes primitives through
12+ * Projects safe public fields from a project document
613 *
7- * @param value - value to stringify
14+ * @param p - project DB record
815 */
9- function str ( value : unknown ) : string {
10- return String ( value ) ;
16+ function projectDTO ( p : ProjectDBScheme ) : Record < string , unknown > {
17+ return {
18+ id : String ( p . _id ) ,
19+ name : p . name ,
20+ workspaceId : String ( p . workspaceId ) ,
21+ image : p . image ?? null ,
22+ } ;
1123}
1224
1325/**
14- * Safe property accessor — returns undefined for missing nested paths
26+ * Projects safe public fields from a workspace document
1527 *
16- * @param obj - source object
17- * @param key - property name
28+ * @param w - workspace DB record
1829 */
19- function get ( obj : Record < string , unknown > , key : string ) : unknown {
20- return obj ?. [ key ] ;
21- }
22-
23- /* ---------- Shared DTO projectors ---------- */
24-
25- function projectDTO ( p : Record < string , unknown > ) : Record < string , unknown > {
26- return {
27- id : str ( get ( p , '_id' ) ) ,
28- name : get ( p , 'name' ) ?? null ,
29- workspaceId : get ( p , 'workspaceId' ) ? str ( get ( p , 'workspaceId' ) ) : null ,
30- image : get ( p , 'image' ) ?? null ,
31- } ;
32- }
33-
34- function workspaceDTO ( w : Record < string , unknown > ) : Record < string , unknown > {
30+ function workspaceDTO ( w : WorkspaceDBScheme ) : Record < string , unknown > {
3531 return {
36- id : str ( get ( w , ' _id' ) ) ,
37- name : get ( w , ' name' ) ?? null ,
38- image : get ( w , ' image' ) ?? null ,
32+ id : String ( w . _id ) ,
33+ name : w . name ,
34+ image : w . image ?? null ,
3935 } ;
4036}
4137
42- function userDTO ( u : Record < string , unknown > ) : Record < string , unknown > {
38+ /**
39+ * Projects safe public fields from a user document (no password, no bank cards)
40+ *
41+ * @param u - user DB record
42+ */
43+ function userDTO ( u : UserDBScheme ) : Record < string , unknown > {
4344 return {
44- id : str ( get ( u , ' _id' ) ) ,
45- name : get ( u , ' name' ) ?? null ,
46- email : get ( u , ' email' ) ?? null ,
47- image : get ( u , ' image' ) ?? null ,
45+ id : String ( u . _id ) ,
46+ name : u . name ?? null ,
47+ email : u . email ?? null ,
48+ image : u . image ?? null ,
4849 } ;
4950}
5051
51- function eventDTO ( e : Record < string , unknown > ) : Record < string , unknown > {
52- const payload = ( e . payload ?? { } ) as Record < string , unknown > ;
53- const backtrace = ( payload . backtrace ?? [ ] ) as Array < Record < string , unknown > > ;
54-
52+ /**
53+ * Projects safe public fields from a grouped event (no sourceCode, no breadcrumbs, no addons)
54+ *
55+ * @param e - decoded grouped event
56+ */
57+ function eventDTO ( e : DecodedGroupedEvent ) : Record < string , unknown > {
5558 return {
56- id : e . _id ? str ( e . _id ) : null ,
57- groupHash : e . groupHash ?? null ,
58- totalCount : e . totalCount ?? null ,
59- catcherType : e . catcherType ?? null ,
60- timestamp : e . timestamp ?? null ,
61- usersAffected : e . usersAffected ?? null ,
62- title : payload . title ?? null ,
63- type : payload . type ?? null ,
64- backtrace : backtrace . map ( ( f ) => ( {
65- file : f . file ?? null ,
66- line : f . line ?? null ,
59+ id : e . _id ? String ( e . _id ) : null ,
60+ groupHash : e . groupHash ,
61+ totalCount : e . totalCount ,
62+ catcherType : e . catcherType ,
63+ timestamp : e . timestamp ,
64+ usersAffected : e . usersAffected ,
65+ title : e . payload . title ,
66+ type : e . payload . type ?? null ,
67+ backtrace : ( e . payload . backtrace ?? [ ] ) . map ( ( f ) => ( {
68+ file : f . file ,
69+ line : f . line ,
6770 column : f . column ?? null ,
6871 function : f . function ?? null ,
6972 } ) ) ,
7073 } ;
7174}
7275
73- function templateEventDataDTO ( item : Record < string , unknown > ) : Record < string , unknown > {
74- const event = ( item . event ?? { } ) as Record < string , unknown > ;
75-
76+ /**
77+ * Projects event list item with its metadata (newCount, daysRepeated, etc.)
78+ *
79+ * @param item - template event data from sender worker
80+ */
81+ function templateEventDataDTO ( item : TemplateEventData ) : Record < string , unknown > {
7682 return {
77- event : eventDTO ( event ) ,
78- newCount : item . newCount ?? null ,
79- daysRepeated : item . daysRepeated ?? null ,
83+ event : eventDTO ( item . event ) ,
84+ newCount : item . newCount ,
85+ daysRepeated : item . daysRepeated ,
8086 usersAffected : item . usersAffected ?? null ,
81- repetitionId : item . repetitionId ? str ( item . repetitionId ) : null ,
87+ repetitionId : item . repetitionId ? String ( item . repetitionId ) : null ,
8288 } ;
8389}
8490
85- function planDTO ( p : Record < string , unknown > ) : Record < string , unknown > {
91+ /**
92+ * Projects safe public fields from a plan document
93+ *
94+ * @param p - plan DB record
95+ */
96+ function planDTO ( p : PlanDBScheme ) : Record < string , unknown > {
8697 return {
87- id : str ( get ( p , ' _id' ) ) ,
88- name : get ( p , ' name' ) ?? null ,
89- eventsLimit : get ( p , ' eventsLimit' ) ?? null ,
90- monthlyCharge : get ( p , ' monthlyCharge' ) ?? null ,
98+ id : String ( p . _id ) ,
99+ name : p . name ,
100+ eventsLimit : p . eventsLimit ,
101+ monthlyCharge : p . monthlyCharge ,
91102 } ;
92103}
93104
94105type PayloadProjector = ( payload : Record < string , unknown > ) => Record < string , unknown > ;
95106
96107const projectors : Record < string , PayloadProjector > = {
97108 'event' : ( p ) => ( {
98- project : projectDTO ( ( p . project ?? { } ) as Record < string , unknown > ) ,
99- events : ( ( p . events ?? [ ] ) as Array < Record < string , unknown > > ) . map ( templateEventDataDTO ) ,
109+ project : p . project ? projectDTO ( p . project as ProjectDBScheme ) : null ,
110+ events : ( ( p . events ?? [ ] ) as TemplateEventData [ ] ) . map ( templateEventDataDTO ) ,
100111 period : p . period ?? null ,
101112 } ) ,
102113
103114 'several-events' : ( p ) => ( {
104- project : projectDTO ( ( p . project ?? { } ) as Record < string , unknown > ) ,
105- events : ( ( p . events ?? [ ] ) as Array < Record < string , unknown > > ) . map ( templateEventDataDTO ) ,
115+ project : p . project ? projectDTO ( p . project as ProjectDBScheme ) : null ,
116+ events : ( ( p . events ?? [ ] ) as TemplateEventData [ ] ) . map ( templateEventDataDTO ) ,
106117 period : p . period ?? null ,
107118 } ) ,
108119
109120 'assignee' : ( p ) => ( {
110- project : projectDTO ( ( p . project ?? { } ) as Record < string , unknown > ) ,
111- event : eventDTO ( ( p . event ?? { } ) as Record < string , unknown > ) ,
112- whoAssigned : userDTO ( ( p . whoAssigned ?? { } ) as Record < string , unknown > ) ,
121+ project : p . project ? projectDTO ( p . project as ProjectDBScheme ) : null ,
122+ event : p . event ? eventDTO ( p . event as DecodedGroupedEvent ) : null ,
123+ whoAssigned : p . whoAssigned ? userDTO ( p . whoAssigned as UserDBScheme ) : null ,
113124 daysRepeated : p . daysRepeated ?? null ,
114125 } ) ,
115126
116127 'block-workspace' : ( p ) => ( {
117- workspace : workspaceDTO ( ( p . workspace ?? { } ) as Record < string , unknown > ) ,
128+ workspace : p . workspace ? workspaceDTO ( p . workspace as WorkspaceDBScheme ) : null ,
118129 } ) ,
119130
120131 'blocked-workspace-reminder' : ( p ) => ( {
121- workspace : workspaceDTO ( ( p . workspace ?? { } ) as Record < string , unknown > ) ,
132+ workspace : p . workspace ? workspaceDTO ( p . workspace as WorkspaceDBScheme ) : null ,
122133 daysAfterBlock : p . daysAfterBlock ?? null ,
123134 } ) ,
124135
125136 'days-limit-almost-reached' : ( p ) => ( {
126- workspace : workspaceDTO ( ( p . workspace ?? { } ) as Record < string , unknown > ) ,
137+ workspace : p . workspace ? workspaceDTO ( p . workspace as WorkspaceDBScheme ) : null ,
127138 daysLeft : p . daysLeft ?? null ,
128139 } ) ,
129140
130141 'events-limit-almost-reached' : ( p ) => ( {
131- workspace : workspaceDTO ( ( p . workspace ?? { } ) as Record < string , unknown > ) ,
142+ workspace : p . workspace ? workspaceDTO ( p . workspace as WorkspaceDBScheme ) : null ,
132143 eventsCount : p . eventsCount ?? null ,
133144 eventsLimit : p . eventsLimit ?? null ,
134145 } ) ,
135146
136147 'payment-failed' : ( p ) => ( {
137- workspace : workspaceDTO ( ( p . workspace ?? { } ) as Record < string , unknown > ) ,
148+ workspace : p . workspace ? workspaceDTO ( p . workspace as WorkspaceDBScheme ) : null ,
138149 reason : p . reason ?? null ,
139150 } ) ,
140151
141152 'payment-success' : ( p ) => ( {
142- workspace : workspaceDTO ( ( p . workspace ?? { } ) as Record < string , unknown > ) ,
143- plan : planDTO ( ( p . plan ?? { } ) as Record < string , unknown > ) ,
153+ workspace : p . workspace ? workspaceDTO ( p . workspace as WorkspaceDBScheme ) : null ,
154+ plan : p . plan ? planDTO ( p . plan as PlanDBScheme ) : null ,
144155 } ) ,
145156
146157 'sign-up' : ( p ) => ( {
@@ -163,9 +174,9 @@ const projectors: Record<string, PayloadProjector> = {
163174 * @param notification - notification with type and payload
164175 */
165176export default function render ( notification : Notification ) : WebhookDelivery {
166- const project = projectors [ notification . type ] ;
167- const payload = project
168- ? project ( notification . payload as unknown as Record < string , unknown > )
177+ const projector = projectors [ notification . type ] ;
178+ const payload = projector
179+ ? projector ( notification . payload as unknown as Record < string , unknown > )
169180 : { } ;
170181
171182 return {
0 commit comments