-
Notifications
You must be signed in to change notification settings - Fork 0
/
interfaces.d.ts
422 lines (377 loc) · 11.8 KB
/
interfaces.d.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
// export type TableName = 'person' | 'personView' | 'account' | 'accountView' | 'parent' | 'teacher' |
// 'hd' | 'child' | 'childView' | 'teacher_child' | 'program' |
// 'programView' | 'field' | 'fieldView' | 'activity' | 'goal' | 'evaluation';
/**
* evaluation's rate won't change GoalState. It's another rate/evaluation
*/
export type EvaluationRate = 'continual' | 'excellent';
export type GoalState = 'continual' | "strength" | "completed";
export type Gender = 'Male' | 'Female';
/**
* Used to check in the frontend. Ex: if action is `login` then open login form.
* Reason: Error message may change. Action is static.
*/
export type Action = '' | 'login' | 'privilege';
export interface ErrorResponse {
/** false dah */
success: boolean;
message: any;
msg: any;
action: any;
sqlMessage: any;
error: {
statusCode: number;
exception: any;
timestamp: string;
};
}
export interface SuccessResponse {
/** true dah */
success: boolean;
data: any;
/** if success false there will be a message */
message?: string;
}
/** success response of findOne/findAll request */
export interface SucResFind {
success: boolean;
/** for findOne by id then max length is one. Or zero -empty array- for not found*/
data: ITableEntity[]//Entity
}
export type Role = 'Admin' | 'HeadOfDepartment' | 'Teacher' | 'Parent';
/**
* User object that stored in request.session.user
*/
export interface User {
isLoggedIn: boolean;
accountId: number;
username: string;
/** account.person.name */
name: string;
roles: Role[];
address?: string;
/**max length is 10 or 0 for not parent */
phones: string[];
birthdate: string;
person: IPersonEntity;
}
export interface ILoginInfo {
username: string;
password: string;
}
export interface ICreateAccount {
username: string;//!Account
password: string;//!Account
personId: number;//!Account
address?: string;//!Parent
phone0?: string;//!Parent
phone1?: string;//!Parent
phone2?: string;//!Parent
phone3?: string;//!Parent
phone4?: string;//!Parent
phone5?: string;//!Parent
phone6?: string;//!Parent
phone7?: string;//!Parent
phone8?: string;//!Parent
phone9?: string;//!Parent
[key: string]: any;
roles: Role[];
}
export interface IAccountEntity extends ICreateAccount {
id: number;
person: IPersonEntity;//!Account
rolesEntities: IRoleEntity[];//!All roles
children: IChildEntity[];//!Parent
evaluations: IEvaluationEntity[];//!Teacher
goals: IGoalEntity[];//!Teacher
teaches: IChildEntity[];//!Teacher
}
export interface IChangePassword {
oldPassword: string;
/**the new password */
password: string;
}
export interface ICreateChild {
femaleFamilyMembers?: number | null;
maleFamilyMembers?: number | null;
birthOrder?: number | null;
parentsKinship?: string | null;
diagnosticDate?: Date | string | null;
pregnancyState?: string | null;
birthState?: string | null;
growthState?: string | null;
diagnostic?: string | null;
medicine?: string | null;
behaviors?: string | null;
prioritySkills?: string | null;
/** Default is false (i.e., NOT archive) */
isArchive?: boolean | null;
parentId?: number | null;
personId: number;
programId?: number;
}
export interface IChildEntity extends ICreateChild {
id: number;
parent?: IAccountEntity | null;
person: IPersonEntity;
goals: IGoalEntity[];
strengths: IStrengthEntity[];
teachers: IAccountEntity[];
program?: IProgramEntity;
familyMembers?: number | null;
/** registerDate: (is person.createdDatetime) */
}
export interface ICreateEvaluation {
description: string;
mainstream?: string;
note?: string;
evaluationDatetime: Date;
rate: EvaluationRate;
goalId: number;
teacherId: number;
}
export interface IEvaluationEntity extends ICreateEvaluation {
id: number;
goal: IGoalEntity;
teacher: IAccountEntity;
}
export interface ICreatePerson {
name: string;
birthDate?: string | null;
gender: Gender;
createdDatetime: Date;
}
export interface IPersonEntity extends ICreatePerson {
id: number;
image?: string;
}
export interface ICreateStrength {
note?: string;
assignDatetime: Date;
activityId: number;
childId: number;
teacherId: number;
}
export interface IStrengthEntity extends ICreateStrength {
id: number;
activity: IActivityEntity;
child: IChildEntity;
evaluations: IEvaluationEntity[];
teacher: IAccountEntity;
}
export interface ICreateGoal extends ICreateStrength {
state: GoalState;
}
export interface IGoalEntity extends ICreateGoal, IStrengthEntity {
}
export interface ICreateActivity {
name: string;
minAge?: number;
maxAge?: number;
fieldId?: number;
programId?: number;
createdDatetime?: Date;
}
export interface IActivityEntity extends ICreateActivity {
id: number;
program?: IProgramEntity;
field?: IFieldEntity;
goals: IGoalEntity[];
}
export interface ICreateField {
name: string;
createdDatetime?: Date;
}
export interface IFieldEntity extends ICreateField {
id: number;
activities: IActivityEntity[];
activityCount: number;
}
export interface ICreateProgram {
name: string;
createdDatetime?: Date;
}
export interface IProgramEntity extends ICreateProgram {
id: number;
activities: IActivityEntity[];
activityCount: number;
}
export interface IRoleEntity {
id: number;
name: Role;
accounts: IAccountEntity[]
}
export type ITableEntity = IProgramEntity | IFieldEntity | IActivityEntity
| IGoalEntity | IPersonEntity | IEvaluationEntity | IChildEntity | IAccountEntity;
/**Success Response of edit/delete methods (DELETE, PATCH) */
export interface SucResEditDel {
generatedMaps?: any[],
raw?: any[],
/**Usually value is `1` because there is one raw affected. dah */
affected: number
}
/**todo notification should not send to all users:
* - if parent get a notification of new goal then indeed that goal have been added to one of the parent's children.
* - if teacher ... then ... have been added to one of his teaching children.
* - if Admin/HeadOfDepartment ... then it means nothing only system's data changed.
*/
export interface INotification {
by: User;
method: 'POST' | 'DELETE' | 'PATCH' | 'PUT' | null;
controller: 'account' | 'activity' | 'child' | 'evaluation' | 'field' | 'goal' | 'backup' | 'restore' | 'program' | 'login' | 'logout' | 'strength';
/**id of the posted/deleted/patched/putted entity */
payloadId: number;
payload: any;
datetime: string | Date;
}
export type TimeframeDuration = 'All Time' | 'Yearly' | 'Monthly' | 'Weekly';
export interface CustomTimeframe {
from: string | Date,
to: string | Date,
}
/** HOW TO CALCULATE IMPROVEMENT/CHANGE RATE:
* To show the change of goals/evaluations...etc within a timeframe (start date (from), end date (to)).
* We need an old/origin value and a new/current value, new is the current value so if the average evaluations within X timeframe is 50% then it is what we call NEW.
* Then what is the old/origin, will let have an example of change rate in Gold prices.
* We can't say how the Gold price rise unless we have the old Gold price.
* But when it comes to the change in the average evaluations rate what will be the old/origin average evaluations rate?
* Let have an example:
* If user chose timeframe such as January (from: 1/1, to: 1/31)
* then we will compare the evaluations of January to the evaluations of December 2022.
* Why? because to compare an improvement/change we should have base to compare to,
* and the base timeframe from a chosen timeframe can not be static, it won't be helpful.
* So, we can't say for example the evaluations in this week improved unless we compare it with the previous week.
* To do this in an arbitrary timeframe such as from: 5/13, to: 7/29 (not static such as Week/Month...etc).
* We first will get all evaluations within the NEW timeframe.
* The OLD/ORIGIN timeframe is the past mirrored of the user's chosen timeframe;
* the past mirror of a timeframe can be easily understand as below:
* February => ~January (Past mirror of January).
* This week => Last week.
* from:2/20, to:2/30 => from:2/10, to:2/20.
* Note: past mirror is made up term :)
* to calculate a past mirror from a timeframe we do the following (Pseudocode):
* ```pseudocode
* //user chosen timeframe
* NewFrom = 4/20;
* NewTo = 4/25;
* daysDuration = NewTo - NewFrom;// 5 days
* OriginFrom = NewFrom - daysDuration;// 4/15
* OriginTo = NewFrom;// 4/20
* ```
* To get the improvement/change of average evaluations rate after we get the evaluations within NEW timeframe and ORIGIN timeframe:
* Calculate the NEW and ORIGIN rate by dividing number Of excellent evaluations over the number of evaluations:
* ```javascript
* rate = numberOfExcellentEvaluations / numberOfEvaluations;
* ```
* Finally after we get NEW rate and ORIGIN rate we calculate the improvement/change rate as following:
* ```javascript
* //improvement/change formula: (new - origin) / origin * 100; You can use this to calculate the raise of Gold price :)
* changeRate = (NewRate - OriginRate) / OriginRate * 100;
* ```
*/
export interface IChildReport {
//some properties can be drive from the same object such as `goalsCount=completedCount+continualCount` but for the sake of simplicity and readability we ignore that
child: IChildEntity;
evaluation: {
evaluationsCount: number,
/** old is used to calculate the change as: (evaluationsCount - oldEvaluationsCount) / oldEvaluationsCount. old is the evaluations within past mirror of chosen timeframe so if timeframe is February then past mirror(old) is January evaluations */
oldEvaluationsCount: number,
/**ExcellentEvaluations / TotalEvaluations. Within the chosen timeframe*/
avgEvaluationsRate: number,
/** old is used to calculate the change as: (newEvaluationsRatePercent - oldEvaluationsRatePercent) / oldEvaluationsRatePercent. old is the evaluations within past mirror of chosen timeframe so if timeframe is February then past mirror(old) is January evaluations */
oldAvgEvaluationsRate: number,
evaluations: {
rate: IEvaluationEntity['rate'],
evaluationDatetime: IEvaluationEntity['evaluationDatetime'],
}[]
},
goal: {
goals: IGoalEntity[],
completedCount: number,
continualCount: number,
goalsCount: number,
oldGoalsCount: number,
/** CompletedGoals / totalGoals */
avgGoalsRate: number,
oldAvgGoalsRate: number,
goalsStrengthsCount: number,
oldGoalsStrengthsCount: number,
/** (CompletedGoals + totalStrengths) / (totalGoals + totalStrengths) */
avgGoalsStrengthsRate: number,
oldAvgGoalsStrengthsRate: number,
},
strength: {
strengths: IStrengthEntity[],
strengthsCount: number,
oldStrengthsCount: number,
},
}
//private used below
interface ACCOUNTS {
all: number;
admin: number;
headOfDepartment: number;
teacher: number;
parent: number;
}
//private used below
interface CHILDREN {
children: IChildEntity[];
childrenNotArchive: number;
childrenArchive: number;
}
//private used below
interface COUNT {
programs: number;
fields: number;
accounts: ACCOUNTS;
completedGoals: number;
continualGoals: number;
strengths: number;
activities: number;
evaluations: number;
specialActivities: number;
}
interface COUNT_TIMEFRAME {
children: CHILDREN;
programs: number;
fields: number;
accounts: ACCOUNTS;
completedGoals: number;
continualGoals: number;
strengths: number;
activities: number;
evaluations: number;
specialActivities: number;
}
//private used below
interface COUNT_ALL_TIME extends COUNT {
children: Omit<CHILDREN, 'children'>
}
/**all time is all time and timeframe is number of entities within the timeframe */
export interface IDashboard {
allTime: COUNT_ALL_TIME;
timeframe: COUNT_TIMEFRAME;
}
export interface NotificationMessage {
from: User,
/**`null` means it is broadcast notification message */
to: User | null,
text: string;
}
export type ITimelineEvent = {
state: 'goal' | 'evaluation' | 'child' | 'strength';
} & ({
state: 'child';
child: IChildEntity;
}
| {
state: 'goal';
goal: IGoalEntity;
} | {
state: 'evaluation';
evaluation: IEvaluationEntity;
} | {
state: 'strength';
strength: IStrengthEntity;
})