@neutron.co.id/pendidikan-operation 1.27.24 → 1.27.26

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.
@@ -11,4 +11,5 @@ export * from './action.getTeacherPoint';
11
11
  export * from './action.getStaffPoint';
12
12
  export * from './studentReport';
13
13
  export * from './updateReportStudent';
14
+ export * from './sendPointNotification';
14
15
  export * from './action.syncStudents';
@@ -0,0 +1,2 @@
1
+ export * from './sendPointNotification.action';
2
+ export * from './sendPointNotification.schema';
@@ -0,0 +1,144 @@
1
+ 'use strict';
2
+
3
+ const operation = require('@neon.id/operation');
4
+ const ofetch = require('ofetch');
5
+ const core = require('@neon.id/core');
6
+ const query = require('@neon.id/query');
7
+ const utils = require('@neon.id/utils');
8
+ const sendPointNotification_schema = require('./sendPointNotification.schema.cjs');
9
+
10
+ const sendPointNotification = operation.Action.define({
11
+ key: "sendPointNotification",
12
+ name: "Send Score Notification",
13
+ type: "command",
14
+ category: "domain",
15
+ execute: async (input, stream) => {
16
+ utils.guard(stream, "streamRequired");
17
+ const config = stream?.context?.config;
18
+ const { validate } = operation.useValidation(stream, sendPointNotification_schema.SendPointNotificationSchema);
19
+ const data = validate(input);
20
+ if (!config?.novuApi?.url || !config?.novuApi?.token) {
21
+ console.warn("Novu API not configured, skipping notification");
22
+ return core.Result.ok({
23
+ state: "emailsSent",
24
+ message: "Novu not configured",
25
+ data: {
26
+ sentCount: 0,
27
+ transactionIds: []
28
+ }
29
+ });
30
+ }
31
+ try {
32
+ const student = await _getOneStudent(stream, data.studentId);
33
+ try {
34
+ await ofetch.ofetch(`${config.novuApi.url}/v1/events/trigger`, {
35
+ method: "POST",
36
+ headers: {
37
+ "Authorization": `ApiKey ${config.novuApi.token}`,
38
+ "Content-Type": "application/json"
39
+ },
40
+ body: JSON.stringify({
41
+ name: "get-point",
42
+ to: {
43
+ subscriberId: student.userId
44
+ },
45
+ payload: {
46
+ point: data?.point
47
+ },
48
+ overrides: {
49
+ fcm: {
50
+ data: {
51
+ userId: String(student.userId),
52
+ moduleType: "get-point",
53
+ moduleId: String(data?.moduleId)
54
+ }
55
+ }
56
+ }
57
+ })
58
+ });
59
+ await stream?.actions.data.createOne.execute({
60
+ model: "neu:data:notification",
61
+ data: {
62
+ userId: student.userId,
63
+ moduleType: "get-point",
64
+ moduleId: data?.moduleId,
65
+ messageData: {
66
+ id: data?.moduleId,
67
+ message: `Kamu baru saja menerima transfer sebesar ${data?.point} poin. Cek transaksinya disini ya!`
68
+ },
69
+ url: `${config?.appFluffyUrl}/transaksi`
70
+ }
71
+ }, stream);
72
+ } catch (error) {
73
+ console.error(`Failed to send score notification to student ${student.userId}:`, error);
74
+ }
75
+ return core.Result.ok({
76
+ state: "notificationSent",
77
+ message: `Sent successfully`,
78
+ data: {
79
+ point: data?.point,
80
+ userId: student.userId
81
+ }
82
+ });
83
+ } catch (error) {
84
+ console.error("Failed to send score notifications:", error);
85
+ return core.Result.ok({
86
+ state: "emailsSent",
87
+ message: "Failed to send notifications",
88
+ data: { sentCount: 0, transactionIds: [] }
89
+ });
90
+ }
91
+ }
92
+ });
93
+ async function _getOneStudent(stream, userId) {
94
+ const result = await stream.actions.data.getMany.execute(
95
+ {
96
+ model: "neu:akademik:student",
97
+ query: query.Query.define({
98
+ filter: {
99
+ userId
100
+ },
101
+ fields: {
102
+ id: 1,
103
+ flag: 1,
104
+ display: 1,
105
+ name: 1,
106
+ birthDate: 1,
107
+ age: 1,
108
+ stageId: 1,
109
+ levelIds: 1,
110
+ branchIds: 1,
111
+ seniorSchoolIds: 1,
112
+ stage: { id: 1, name: 1 },
113
+ levels: { id: 1, name: 1 },
114
+ branches: { id: 1, name: 1 },
115
+ user: {
116
+ roles: {
117
+ name: 1,
118
+ handle: 1
119
+ }
120
+ },
121
+ seniorSchools: { id: 1, name: 1 },
122
+ classGroups: {
123
+ id: 1,
124
+ name: 1
125
+ },
126
+ nis: 1,
127
+ nis2: 1,
128
+ phoneSms: 1,
129
+ phone: 1,
130
+ whatsapp: 1,
131
+ email: 1,
132
+ note: 1,
133
+ point: 1
134
+ }
135
+ })
136
+ },
137
+ stream
138
+ );
139
+ if (result.isFailure)
140
+ throw result;
141
+ return result.value[0];
142
+ }
143
+
144
+ exports.sendPointNotification = sendPointNotification;
@@ -0,0 +1,8 @@
1
+ import { Action } from '@neon.id/operation';
2
+ import { type SendPointNotificationMeta, type SendPointNotificationOutput } from './sendPointNotification.schema';
3
+ export declare const sendPointNotification: Action<"sendPointNotification", {
4
+ point: number;
5
+ studentId: string;
6
+ moduleId: string;
7
+ moduleType: string;
8
+ }, SendPointNotificationOutput, SendPointNotificationMeta>;
@@ -0,0 +1,142 @@
1
+ import { Action, useValidation } from '@neon.id/operation';
2
+ import { ofetch } from 'ofetch';
3
+ import { Result } from '@neon.id/core';
4
+ import { Query } from '@neon.id/query';
5
+ import { guard } from '@neon.id/utils';
6
+ import { SendPointNotificationSchema } from './sendPointNotification.schema.mjs';
7
+
8
+ const sendPointNotification = Action.define({
9
+ key: "sendPointNotification",
10
+ name: "Send Score Notification",
11
+ type: "command",
12
+ category: "domain",
13
+ execute: async (input, stream) => {
14
+ guard(stream, "streamRequired");
15
+ const config = stream?.context?.config;
16
+ const { validate } = useValidation(stream, SendPointNotificationSchema);
17
+ const data = validate(input);
18
+ if (!config?.novuApi?.url || !config?.novuApi?.token) {
19
+ console.warn("Novu API not configured, skipping notification");
20
+ return Result.ok({
21
+ state: "emailsSent",
22
+ message: "Novu not configured",
23
+ data: {
24
+ sentCount: 0,
25
+ transactionIds: []
26
+ }
27
+ });
28
+ }
29
+ try {
30
+ const student = await _getOneStudent(stream, data.studentId);
31
+ try {
32
+ await ofetch(`${config.novuApi.url}/v1/events/trigger`, {
33
+ method: "POST",
34
+ headers: {
35
+ "Authorization": `ApiKey ${config.novuApi.token}`,
36
+ "Content-Type": "application/json"
37
+ },
38
+ body: JSON.stringify({
39
+ name: "get-point",
40
+ to: {
41
+ subscriberId: student.userId
42
+ },
43
+ payload: {
44
+ point: data?.point
45
+ },
46
+ overrides: {
47
+ fcm: {
48
+ data: {
49
+ userId: String(student.userId),
50
+ moduleType: "get-point",
51
+ moduleId: String(data?.moduleId)
52
+ }
53
+ }
54
+ }
55
+ })
56
+ });
57
+ await stream?.actions.data.createOne.execute({
58
+ model: "neu:data:notification",
59
+ data: {
60
+ userId: student.userId,
61
+ moduleType: "get-point",
62
+ moduleId: data?.moduleId,
63
+ messageData: {
64
+ id: data?.moduleId,
65
+ message: `Kamu baru saja menerima transfer sebesar ${data?.point} poin. Cek transaksinya disini ya!`
66
+ },
67
+ url: `${config?.appFluffyUrl}/transaksi`
68
+ }
69
+ }, stream);
70
+ } catch (error) {
71
+ console.error(`Failed to send score notification to student ${student.userId}:`, error);
72
+ }
73
+ return Result.ok({
74
+ state: "notificationSent",
75
+ message: `Sent successfully`,
76
+ data: {
77
+ point: data?.point,
78
+ userId: student.userId
79
+ }
80
+ });
81
+ } catch (error) {
82
+ console.error("Failed to send score notifications:", error);
83
+ return Result.ok({
84
+ state: "emailsSent",
85
+ message: "Failed to send notifications",
86
+ data: { sentCount: 0, transactionIds: [] }
87
+ });
88
+ }
89
+ }
90
+ });
91
+ async function _getOneStudent(stream, userId) {
92
+ const result = await stream.actions.data.getMany.execute(
93
+ {
94
+ model: "neu:akademik:student",
95
+ query: Query.define({
96
+ filter: {
97
+ userId
98
+ },
99
+ fields: {
100
+ id: 1,
101
+ flag: 1,
102
+ display: 1,
103
+ name: 1,
104
+ birthDate: 1,
105
+ age: 1,
106
+ stageId: 1,
107
+ levelIds: 1,
108
+ branchIds: 1,
109
+ seniorSchoolIds: 1,
110
+ stage: { id: 1, name: 1 },
111
+ levels: { id: 1, name: 1 },
112
+ branches: { id: 1, name: 1 },
113
+ user: {
114
+ roles: {
115
+ name: 1,
116
+ handle: 1
117
+ }
118
+ },
119
+ seniorSchools: { id: 1, name: 1 },
120
+ classGroups: {
121
+ id: 1,
122
+ name: 1
123
+ },
124
+ nis: 1,
125
+ nis2: 1,
126
+ phoneSms: 1,
127
+ phone: 1,
128
+ whatsapp: 1,
129
+ email: 1,
130
+ note: 1,
131
+ point: 1
132
+ }
133
+ })
134
+ },
135
+ stream
136
+ );
137
+ if (result.isFailure)
138
+ throw result;
139
+ return result.value[0];
140
+ }
141
+
142
+ export { sendPointNotification };
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ const z = require('@neon.id/z');
4
+
5
+ const SendPointNotificationSchema = z.z.object({
6
+ studentId: z.z.objectId().explain({ label: "Student ID" }),
7
+ moduleId: z.z.string().explain({ label: "Module ID" }),
8
+ moduleType: z.z.string().explain({ label: "Module Type" }),
9
+ point: z.z.number().explain({ label: "Point Get" })
10
+ });
11
+
12
+ exports.SendPointNotificationSchema = SendPointNotificationSchema;
@@ -0,0 +1,24 @@
1
+ import { z } from '@neon.id/z';
2
+ export declare const SendPointNotificationSchema: z.ZodObject<{
3
+ studentId: z.ZodEffects<z.ZodString, string, string>;
4
+ moduleId: z.ZodString;
5
+ moduleType: z.ZodString;
6
+ point: z.ZodNumber;
7
+ }, "strip", z.ZodTypeAny, {
8
+ point: number;
9
+ studentId: string;
10
+ moduleId: string;
11
+ moduleType: string;
12
+ }, {
13
+ point: number;
14
+ studentId: string;
15
+ moduleId: string;
16
+ moduleType: string;
17
+ }>;
18
+ export type SendPointNotificationInput = z.parse<typeof SendPointNotificationSchema>;
19
+ export interface SendPointNotificationOutput {
20
+ }
21
+ export interface SendPointNotificationMeta {
22
+ input: SendPointNotificationInput;
23
+ output: SendPointNotificationOutput;
24
+ }
@@ -0,0 +1,10 @@
1
+ import { z } from '@neon.id/z';
2
+
3
+ const SendPointNotificationSchema = z.object({
4
+ studentId: z.objectId().explain({ label: "Student ID" }),
5
+ moduleId: z.string().explain({ label: "Module ID" }),
6
+ moduleType: z.string().explain({ label: "Module Type" }),
7
+ point: z.number().explain({ label: "Point Get" })
8
+ });
9
+
10
+ export { SendPointNotificationSchema };
package/build/index.cjs CHANGED
@@ -16,6 +16,7 @@ const action_getTeacherPoint = require('./actions/akademik/action.getTeacherPoin
16
16
  const action_getStaffPoint = require('./actions/akademik/action.getStaffPoint.cjs');
17
17
  const replaceModuleAccess_action = require('./actions/replaceModuleAccess/replaceModuleAccess.action.cjs');
18
18
  const refreshModuleAccess_action = require('./actions/refreshModuleAccess/refreshModuleAccess.action.cjs');
19
+ const sendPointNotification_action = require('./actions/akademik/sendPointNotification/sendPointNotification.action.cjs');
19
20
  const action_allConflict = require('./actions/jadwal/action.allConflict.cjs');
20
21
  const action_classSessionInventoryOccurs = require('./actions/jadwal/action.classSessionInventoryOccurs.cjs');
21
22
  const action_classSessionInventoryPreparation = require('./actions/jadwal/action.classSessionInventoryPreparation.cjs');
@@ -64,6 +65,7 @@ const action_createGradingAndScores = require('./actions/rasionalisasi/action.cr
64
65
  const action_updateGradingAndScores = require('./actions/rasionalisasi/action.updateGradingAndScores.cjs');
65
66
  const syncStudentReport_schema = require('./actions/akademik/studentReport/syncStudentReport.schema.cjs');
66
67
  const updateReportStudent_schema = require('./actions/akademik/updateReportStudent/updateReportStudent.schema.cjs');
68
+ const sendPointNotification_schema = require('./actions/akademik/sendPointNotification/sendPointNotification.schema.cjs');
67
69
  const getClassSessionConflicts_schema = require('./actions/jadwal/getClassSessionConflicts/getClassSessionConflicts.schema.cjs');
68
70
  const syncClassSessions_schema = require('./actions/jadwal/syncClassSessions/syncClassSessions.schema.cjs');
69
71
  const setAksesModulSiswaDiClassGroup_schema = require('./actions/jadwal/setAksesModulSiswaDiClassGroup/setAksesModulSiswaDiClassGroup.schema.cjs');
@@ -105,6 +107,7 @@ const actions = {
105
107
  replaceModuleAccess: replaceModuleAccess_action.replaceModuleAccess,
106
108
  refreshModuleAccess: refreshModuleAccess_action.refreshModuleAccess,
107
109
  replaceModuleAccessManyStudent: replaceModuleAccessManyStudent_action.replaceModuleAccessManyStudent,
110
+ sendPointNotification: sendPointNotification_action.sendPointNotification,
108
111
  // Jadwal
109
112
  allConflict: action_allConflict.allConflict,
110
113
  classSessionInventoryOccurs: action_classSessionInventoryOccurs.classSessionInventoryOccurs,
@@ -174,6 +177,7 @@ exports.getTeacherPoint = action_getTeacherPoint.getTeacherPoint;
174
177
  exports.getStaffPoint = action_getStaffPoint.getStaffPoint;
175
178
  exports.replaceModuleAccess = replaceModuleAccess_action.replaceModuleAccess;
176
179
  exports.refreshModuleAccess = refreshModuleAccess_action.refreshModuleAccess;
180
+ exports.sendPointNotification = sendPointNotification_action.sendPointNotification;
177
181
  exports.allConflict = action_allConflict.allConflict;
178
182
  exports.classSessionInventoryOccurs = action_classSessionInventoryOccurs.classSessionInventoryOccurs;
179
183
  exports.classSessionInventoryPreparation = action_classSessionInventoryPreparation.classSessionInventoryPreparation;
@@ -224,6 +228,7 @@ exports.createGradingAndScores = action_createGradingAndScores.createGradingAndS
224
228
  exports.updateGradingAndScores = action_updateGradingAndScores.updateGradingAndScores;
225
229
  exports.StudentReportSchema = syncStudentReport_schema.StudentReportSchema;
226
230
  exports.UpdateReportStudentSchema = updateReportStudent_schema.UpdateReportStudentSchema;
231
+ exports.SendPointNotificationSchema = sendPointNotification_schema.SendPointNotificationSchema;
227
232
  exports.GetClassSessionConflictsSchema = getClassSessionConflicts_schema.GetClassSessionConflictsSchema;
228
233
  exports.SyncClassSessionsSchema = syncClassSessions_schema.SyncClassSessionsSchema;
229
234
  exports.SetAksesModulSiswaDiClassGroupSchema = setAksesModulSiswaDiClassGroup_schema.SetAksesModulSiswaDiClassGroupSchema;
package/build/index.d.ts CHANGED
@@ -48,6 +48,12 @@ export declare const actions: {
48
48
  studentIds?: string[] | undefined;
49
49
  staffId?: string | undefined;
50
50
  }, import("./actions").ReplaceModuleAccessManyStudentOutput, import("./actions").ReplaceModuleAccessManyStudentMeta>;
51
+ sendPointNotification: import("@neon.id/operation").Action<"sendPointNotification", {
52
+ point: number;
53
+ studentId: string;
54
+ moduleId: string;
55
+ moduleType: string;
56
+ }, import("./actions").SendPointNotificationOutput, import("./actions").SendPointNotificationMeta>;
51
57
  allConflict: import("@neon.id/operation").Action<"allConflict", import("./actions").AllConflictInput, import("./actions").AllConflictOutput, import("./actions").AllConflictMeta>;
52
58
  classSessionInventoryOccurs: import("@neon.id/operation").Action<"classSessionInventoryOccurs", import("./actions").ClassSessionInventoryOccursInput, import("./actions").ClassSessionInventoryOccursOutput, import("./actions").ClassSessionInventoryOccursMeta>;
53
59
  classSessionInventoryPreparation: import("@neon.id/operation").Action<"classSessionInventoryPreparation", import("./actions").ClassSessionInventoryPreparationInput, import("./actions").ClassSessionInventoryPreparationOutput, import("./actions").ClassSessionInventoryPreparationMeta>;
package/build/index.mjs CHANGED
@@ -14,6 +14,7 @@ import { getTeacherPoint } from './actions/akademik/action.getTeacherPoint.mjs';
14
14
  import { getStaffPoint } from './actions/akademik/action.getStaffPoint.mjs';
15
15
  import { replaceModuleAccess } from './actions/replaceModuleAccess/replaceModuleAccess.action.mjs';
16
16
  import { refreshModuleAccess } from './actions/refreshModuleAccess/refreshModuleAccess.action.mjs';
17
+ import { sendPointNotification } from './actions/akademik/sendPointNotification/sendPointNotification.action.mjs';
17
18
  import { allConflict } from './actions/jadwal/action.allConflict.mjs';
18
19
  import { classSessionInventoryOccurs } from './actions/jadwal/action.classSessionInventoryOccurs.mjs';
19
20
  import { classSessionInventoryPreparation } from './actions/jadwal/action.classSessionInventoryPreparation.mjs';
@@ -64,6 +65,7 @@ import { createGradingAndScores } from './actions/rasionalisasi/action.createGra
64
65
  import { updateGradingAndScores } from './actions/rasionalisasi/action.updateGradingAndScores.mjs';
65
66
  export { StudentReportSchema } from './actions/akademik/studentReport/syncStudentReport.schema.mjs';
66
67
  export { UpdateReportStudentSchema } from './actions/akademik/updateReportStudent/updateReportStudent.schema.mjs';
68
+ export { SendPointNotificationSchema } from './actions/akademik/sendPointNotification/sendPointNotification.schema.mjs';
67
69
  export { GetClassSessionConflictsSchema } from './actions/jadwal/getClassSessionConflicts/getClassSessionConflicts.schema.mjs';
68
70
  export { SyncClassSessionsSchema } from './actions/jadwal/syncClassSessions/syncClassSessions.schema.mjs';
69
71
  export { SetAksesModulSiswaDiClassGroupSchema } from './actions/jadwal/setAksesModulSiswaDiClassGroup/setAksesModulSiswaDiClassGroup.schema.mjs';
@@ -105,6 +107,7 @@ const actions = {
105
107
  replaceModuleAccess,
106
108
  refreshModuleAccess,
107
109
  replaceModuleAccessManyStudent,
110
+ sendPointNotification,
108
111
  // Jadwal
109
112
  allConflict,
110
113
  classSessionInventoryOccurs,
@@ -158,4 +161,4 @@ const actions = {
158
161
  syncStudents
159
162
  };
160
163
 
161
- export { acceptQuestion, actions, addManyGradingComponent, allConflict, bulkDeleteSession, bulkUpdateSession, calculateGrading, calculateManyComparator, calculateOneComparator, checkClassAttendance, classSessionInventoryOccurs, classSessionInventoryPreparation, clearAllOverrides, clearGrading, clearOneOverrides, createGradingAndScores, createManySession, customSaveOneClassSession, deleteManySession, editAnswer, generateGrading, getClassSessionConflicts, getGradingCount, getQuestionCount, getStaffId, getStaffPoint, getStudentId, getStudentPoint, getTeacherPoint, hasUnderstand, importData, notUnderstand, prepareConflict, prepareExperience, prepareMediaScanterGradingInsert, presenceSessionStudent, presenceSessionTeacher, rasionalizeGrading, refreshGrading, refreshManyGrading, refreshModuleAccess, reminderQuestions, replaceModuleAccess, replaceModuleAccessManyStudent, sendAnswer, sendClassConsultationNotification, sendClassSessionNotification, sendQuestion, sendScoreNotification, setAksesModulSiswaDiClassGroup, setTravelWageSessions, syncClassGroups, syncClassSessions, syncCommitment, syncStudentAdmisi, syncStudentBranch, syncStudentInformation, syncStudentReport, syncStudents, updateGradingAndScores, updateMany, updateReportStudent, userCountStats };
164
+ export { acceptQuestion, actions, addManyGradingComponent, allConflict, bulkDeleteSession, bulkUpdateSession, calculateGrading, calculateManyComparator, calculateOneComparator, checkClassAttendance, classSessionInventoryOccurs, classSessionInventoryPreparation, clearAllOverrides, clearGrading, clearOneOverrides, createGradingAndScores, createManySession, customSaveOneClassSession, deleteManySession, editAnswer, generateGrading, getClassSessionConflicts, getGradingCount, getQuestionCount, getStaffId, getStaffPoint, getStudentId, getStudentPoint, getTeacherPoint, hasUnderstand, importData, notUnderstand, prepareConflict, prepareExperience, prepareMediaScanterGradingInsert, presenceSessionStudent, presenceSessionTeacher, rasionalizeGrading, refreshGrading, refreshManyGrading, refreshModuleAccess, reminderQuestions, replaceModuleAccess, replaceModuleAccessManyStudent, sendAnswer, sendClassConsultationNotification, sendClassSessionNotification, sendPointNotification, sendQuestion, sendScoreNotification, setAksesModulSiswaDiClassGroup, setTravelWageSessions, syncClassGroups, syncClassSessions, syncCommitment, syncStudentAdmisi, syncStudentBranch, syncStudentInformation, syncStudentReport, syncStudents, updateGradingAndScores, updateMany, updateReportStudent, userCountStats };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neutron.co.id/pendidikan-operation",
3
- "version": "1.27.24",
3
+ "version": "1.27.26",
4
4
  "description": "Operation package of Neutron Pendidikan.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "contributors": [
@@ -86,5 +86,5 @@
86
86
  "publishConfig": {
87
87
  "access": "public"
88
88
  },
89
- "build": 149
89
+ "build": 151
90
90
  }