@hed-hog/lms 0.0.331 → 0.0.338
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/class-group/class-group.controller.d.ts +3 -3
- package/dist/class-group/class-group.service.d.ts +3 -3
- package/dist/course/course.service.d.ts.map +1 -1
- package/dist/course/course.service.js +12 -20
- package/dist/course/course.service.js.map +1 -1
- package/dist/enterprise/enterprise.controller.d.ts +72 -0
- package/dist/enterprise/enterprise.controller.d.ts.map +1 -1
- package/dist/enterprise/enterprise.controller.js +10 -0
- package/dist/enterprise/enterprise.controller.js.map +1 -1
- package/dist/enterprise/enterprise.service.d.ts +78 -0
- package/dist/enterprise/enterprise.service.d.ts.map +1 -1
- package/dist/enterprise/enterprise.service.js +413 -40
- package/dist/enterprise/enterprise.service.js.map +1 -1
- package/dist/enterprise/training/training-admin.controller.d.ts +6 -3
- package/dist/enterprise/training/training-admin.controller.d.ts.map +1 -1
- package/dist/enterprise/training/training-admin.controller.js +10 -6
- package/dist/enterprise/training/training-admin.controller.js.map +1 -1
- package/dist/enterprise/training/training-admin.service.d.ts +8 -2
- package/dist/enterprise/training/training-admin.service.d.ts.map +1 -1
- package/dist/enterprise/training/training-admin.service.js +108 -52
- package/dist/enterprise/training/training-admin.service.js.map +1 -1
- package/dist/enterprise/training/training-viewer.controller.d.ts +3 -0
- package/dist/enterprise/training/training-viewer.controller.d.ts.map +1 -1
- package/dist/evaluation/evaluation.controller.d.ts +4 -4
- package/dist/evaluation/evaluation.service.d.ts +4 -4
- package/dist/instructor/dto/create-instructor-skill.dto.d.ts +0 -4
- package/dist/instructor/dto/create-instructor-skill.dto.d.ts.map +1 -1
- package/dist/instructor/dto/create-instructor-skill.dto.js +0 -21
- package/dist/instructor/dto/create-instructor-skill.dto.js.map +1 -1
- package/dist/instructor/dto/update-instructor-skill.dto.d.ts +0 -4
- package/dist/instructor/dto/update-instructor-skill.dto.d.ts.map +1 -1
- package/dist/instructor/dto/update-instructor-skill.dto.js +0 -22
- package/dist/instructor/dto/update-instructor-skill.dto.js.map +1 -1
- package/dist/instructor/instructor-skill.controller.d.ts +4 -4
- package/dist/instructor/instructor-skill.service.d.ts +4 -7
- package/dist/instructor/instructor-skill.service.d.ts.map +1 -1
- package/dist/instructor/instructor-skill.service.js +2 -89
- package/dist/instructor/instructor-skill.service.js.map +1 -1
- package/dist/instructor/instructor.controller.d.ts +20 -0
- package/dist/instructor/instructor.controller.d.ts.map +1 -1
- package/dist/instructor/instructor.controller.js +19 -0
- package/dist/instructor/instructor.controller.js.map +1 -1
- package/dist/instructor/instructor.service.d.ts +25 -0
- package/dist/instructor/instructor.service.d.ts.map +1 -1
- package/dist/instructor/instructor.service.js +70 -18
- package/dist/instructor/instructor.service.js.map +1 -1
- package/dist/lms.module.d.ts.map +1 -1
- package/dist/lms.module.js.map +1 -1
- package/hedhog/data/route.yaml +23 -1
- package/hedhog/frontend/app/_components/class-form-sheet.tsx.ejs +42 -24
- package/hedhog/frontend/app/_components/course-form-sheet.tsx.ejs +3 -3
- package/hedhog/frontend/app/_components/create-lms-instructor-sheet.tsx.ejs +591 -0
- package/hedhog/frontend/app/certificates/issued/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/certificates/models/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/classes/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/courses/[id]/_components/CourseClassificationCard.tsx.ejs +3 -33
- package/hedhog/frontend/app/courses/[id]/_components/CourseContentCard.tsx.ejs +9 -9
- package/hedhog/frontend/app/courses/[id]/_components/CourseMainInfoCard.tsx.ejs +109 -0
- package/hedhog/frontend/app/courses/[id]/_components/CourseMultiEntityPicker.tsx.ejs +40 -13
- package/hedhog/frontend/app/courses/[id]/_components/CourseRelationsCard.tsx.ejs +76 -81
- package/hedhog/frontend/app/courses/[id]/_components/CourseSummaryCard.tsx.ejs +60 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-scheduled-classes-tab.tsx.ejs +406 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree.tsx.ejs +134 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-course.tsx.ejs +113 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-lesson.tsx.ejs +314 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-session.tsx.ejs +174 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/editor-course.tsx.ejs +242 -33
- package/hedhog/frontend/app/courses/[id]/structure/_components/mock-data.ts.ejs +185 -0
- package/hedhog/frontend/app/courses/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/enterprise/_components/enterprise-activity-timeline.tsx.ejs +87 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-admin-create-sheet.tsx.ejs +4 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-administrators-tab.tsx.ejs +31 -5
- package/hedhog/frontend/app/enterprise/_components/enterprise-classes-tab.tsx.ejs +79 -20
- package/hedhog/frontend/app/enterprise/_components/enterprise-company-identity-card.tsx.ejs +11 -2
- package/hedhog/frontend/app/enterprise/_components/enterprise-course-edit-sheet.tsx.ejs +201 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-courses-tab.tsx.ejs +55 -24
- package/hedhog/frontend/app/enterprise/_components/enterprise-detail-sheet.tsx.ejs +430 -296
- package/hedhog/frontend/app/enterprise/_components/enterprise-mocks.ts.ejs +277 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-overview-analytics.tsx.ejs +205 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-person-edit-sheet.tsx.ejs +97 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-sheet.tsx.ejs +82 -57
- package/hedhog/frontend/app/enterprise/_components/enterprise-student-create-sheet.tsx.ejs +4 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-students-tab.tsx.ejs +60 -22
- package/hedhog/frontend/app/enterprise/_components/enterprise-types.ts.ejs +54 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-user-create-sheet.tsx.ejs +211 -0
- package/hedhog/frontend/app/enterprise/page.tsx.ejs +39 -7
- package/hedhog/frontend/app/exams/[id]/questions/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/exams/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/instructor-skills/page.tsx.ejs +51 -104
- package/hedhog/frontend/app/instructors/_components/instructor-form-sheet.tsx.ejs +625 -366
- package/hedhog/frontend/app/instructors/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/paths/page.tsx.ejs +9 -4
- package/hedhog/frontend/app/reports/evaluations/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/training/page.tsx.ejs +9 -4
- package/hedhog/frontend/messages/en.json +101 -10
- package/hedhog/frontend/messages/pt.json +101 -10
- package/hedhog/table/enterprise_student_license_event.yaml +30 -0
- package/hedhog/table/instructor_skill.yaml +0 -11
- package/package.json +7 -7
- package/src/course/course.service.ts +12 -24
- package/src/enterprise/enterprise.controller.ts +5 -0
- package/src/enterprise/enterprise.service.ts +507 -29
- package/src/enterprise/training/training-admin.controller.ts +4 -0
- package/src/enterprise/training/training-admin.service.ts +115 -51
- package/src/instructor/dto/create-instructor-skill.dto.ts +0 -17
- package/src/instructor/dto/update-instructor-skill.dto.ts +0 -18
- package/src/instructor/instructor-skill.service.ts +2 -97
- package/src/instructor/instructor.controller.ts +16 -0
- package/src/instructor/instructor.service.ts +85 -10
- package/src/lms.module.ts +1 -0
|
@@ -81,6 +81,7 @@ let EnterpriseService = class EnterpriseService {
|
|
|
81
81
|
id: true,
|
|
82
82
|
name: true,
|
|
83
83
|
type: true,
|
|
84
|
+
avatar_id: true,
|
|
84
85
|
},
|
|
85
86
|
},
|
|
86
87
|
_count: {
|
|
@@ -135,6 +136,140 @@ let EnterpriseService = class EnterpriseService {
|
|
|
135
136
|
await this.assertEnterpriseExists(id);
|
|
136
137
|
return this.prisma.enterprise.update({ where: { id }, data: dto });
|
|
137
138
|
}
|
|
139
|
+
async getOverview(id) {
|
|
140
|
+
const enterprise = await this.getById(id);
|
|
141
|
+
if (!enterprise)
|
|
142
|
+
return null;
|
|
143
|
+
const eventModel = this.prisma.enterprise_student_license_event;
|
|
144
|
+
const now = new Date();
|
|
145
|
+
const timelineStart = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() - 11, 1));
|
|
146
|
+
const [studentRows, scheduledClasses, licenseEvents, recentCourses, recentClasses, recentStudents, recentAdmins,] = await Promise.all([
|
|
147
|
+
this.prisma.enterprise_student.findMany({
|
|
148
|
+
where: { enterprise_id: id },
|
|
149
|
+
select: {
|
|
150
|
+
person_id: true,
|
|
151
|
+
status: true,
|
|
152
|
+
created_at: true,
|
|
153
|
+
person: { select: { id: true, name: true } },
|
|
154
|
+
},
|
|
155
|
+
}),
|
|
156
|
+
this.prisma.enterprise_class_group.findMany({
|
|
157
|
+
where: {
|
|
158
|
+
enterprise_id: id,
|
|
159
|
+
course_class_group: { status: { in: ['open', 'ongoing'] } },
|
|
160
|
+
},
|
|
161
|
+
select: {
|
|
162
|
+
created_at: true,
|
|
163
|
+
course_class_group: {
|
|
164
|
+
select: {
|
|
165
|
+
id: true,
|
|
166
|
+
code: true,
|
|
167
|
+
title: true,
|
|
168
|
+
status: true,
|
|
169
|
+
capacity: true,
|
|
170
|
+
course: { select: { title: true } },
|
|
171
|
+
_count: {
|
|
172
|
+
select: {
|
|
173
|
+
course_enrollment: {
|
|
174
|
+
where: { status: { not: 'cancelled' } },
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
}),
|
|
182
|
+
eventModel
|
|
183
|
+
? eventModel
|
|
184
|
+
.findMany({
|
|
185
|
+
where: { enterprise_id: id },
|
|
186
|
+
orderBy: { created_at: 'asc' },
|
|
187
|
+
select: {
|
|
188
|
+
person_id: true,
|
|
189
|
+
event_type: true,
|
|
190
|
+
previous_status: true,
|
|
191
|
+
next_status: true,
|
|
192
|
+
created_at: true,
|
|
193
|
+
person: { select: { id: true, name: true } },
|
|
194
|
+
},
|
|
195
|
+
})
|
|
196
|
+
.catch(() => [])
|
|
197
|
+
: Promise.resolve([]),
|
|
198
|
+
this.prisma.enterprise_course.findMany({
|
|
199
|
+
where: { enterprise_id: id },
|
|
200
|
+
take: 5,
|
|
201
|
+
orderBy: { created_at: 'desc' },
|
|
202
|
+
select: {
|
|
203
|
+
created_at: true,
|
|
204
|
+
course: { select: { id: true, title: true } },
|
|
205
|
+
},
|
|
206
|
+
}),
|
|
207
|
+
this.prisma.enterprise_class_group.findMany({
|
|
208
|
+
where: { enterprise_id: id },
|
|
209
|
+
take: 5,
|
|
210
|
+
orderBy: { created_at: 'desc' },
|
|
211
|
+
select: {
|
|
212
|
+
created_at: true,
|
|
213
|
+
course_class_group: {
|
|
214
|
+
select: {
|
|
215
|
+
id: true,
|
|
216
|
+
code: true,
|
|
217
|
+
title: true,
|
|
218
|
+
course: { select: { title: true } },
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
}),
|
|
223
|
+
this.prisma.enterprise_student.findMany({
|
|
224
|
+
where: { enterprise_id: id },
|
|
225
|
+
take: 5,
|
|
226
|
+
orderBy: { created_at: 'desc' },
|
|
227
|
+
select: {
|
|
228
|
+
created_at: true,
|
|
229
|
+
person: { select: { id: true, name: true } },
|
|
230
|
+
},
|
|
231
|
+
}),
|
|
232
|
+
this.prisma.enterprise_user.findMany({
|
|
233
|
+
where: { enterprise_id: id },
|
|
234
|
+
take: 5,
|
|
235
|
+
orderBy: { created_at: 'desc' },
|
|
236
|
+
select: {
|
|
237
|
+
created_at: true,
|
|
238
|
+
role: true,
|
|
239
|
+
user: { select: { id: true, name: true } },
|
|
240
|
+
},
|
|
241
|
+
}),
|
|
242
|
+
]);
|
|
243
|
+
const used = studentRows.length;
|
|
244
|
+
const limit = enterprise.licenseLimit;
|
|
245
|
+
const available = limit === null ? null : Math.max(limit - used, 0);
|
|
246
|
+
const percent = limit && limit > 0 ? Math.min(100, Math.round((used / limit) * 100)) : 0;
|
|
247
|
+
const capacity = scheduledClasses.reduce((sum, row) => { var _a, _b; return sum + Math.max((_b = (_a = row.course_class_group) === null || _a === void 0 ? void 0 : _a.capacity) !== null && _b !== void 0 ? _b : 0, 0); }, 0);
|
|
248
|
+
const seatsUsed = scheduledClasses.reduce((sum, row) => { var _a, _b, _c; return sum + ((_c = (_b = (_a = row.course_class_group) === null || _a === void 0 ? void 0 : _a._count) === null || _b === void 0 ? void 0 : _b.course_enrollment) !== null && _c !== void 0 ? _c : 0); }, 0);
|
|
249
|
+
return {
|
|
250
|
+
account: enterprise,
|
|
251
|
+
kpis: {
|
|
252
|
+
students: enterprise.studentsCount,
|
|
253
|
+
classes: enterprise.classesCount,
|
|
254
|
+
courses: enterprise.coursesCount,
|
|
255
|
+
administrators: enterprise.adminsCount + enterprise.managersCount,
|
|
256
|
+
portalEnabled: enterprise.portalEnabled,
|
|
257
|
+
},
|
|
258
|
+
licenseUsage: {
|
|
259
|
+
used,
|
|
260
|
+
limit,
|
|
261
|
+
available,
|
|
262
|
+
percent,
|
|
263
|
+
},
|
|
264
|
+
scheduledSeats: {
|
|
265
|
+
used: seatsUsed,
|
|
266
|
+
open: Math.max(capacity - seatsUsed, 0),
|
|
267
|
+
capacity,
|
|
268
|
+
},
|
|
269
|
+
licenseTimeline: this.buildLicenseTimeline(studentRows, licenseEvents, timelineStart, now),
|
|
270
|
+
activities: this.buildEnterpriseActivities(licenseEvents, recentCourses, recentClasses, recentStudents, recentAdmins),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
138
273
|
async delete(id) {
|
|
139
274
|
await this.assertEnterpriseExists(id);
|
|
140
275
|
return this.prisma.enterprise.delete({ where: { id } });
|
|
@@ -149,6 +284,154 @@ let EnterpriseService = class EnterpriseService {
|
|
|
149
284
|
throw new common_1.NotFoundException(`Enterprise #${id} not found`);
|
|
150
285
|
return exists;
|
|
151
286
|
}
|
|
287
|
+
async recordLicenseEvent(params) {
|
|
288
|
+
var _a, _b;
|
|
289
|
+
const eventModel = this.prisma.enterprise_student_license_event;
|
|
290
|
+
if (!eventModel)
|
|
291
|
+
return;
|
|
292
|
+
try {
|
|
293
|
+
await eventModel.create({
|
|
294
|
+
data: {
|
|
295
|
+
enterprise_id: params.enterpriseId,
|
|
296
|
+
person_id: params.personId,
|
|
297
|
+
event_type: params.eventType,
|
|
298
|
+
previous_status: (_a = params.previousStatus) !== null && _a !== void 0 ? _a : null,
|
|
299
|
+
next_status: (_b = params.nextStatus) !== null && _b !== void 0 ? _b : null,
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
catch (_c) {
|
|
304
|
+
// The YAML/DB apply step may not have run yet in older environments.
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
monthKey(date) {
|
|
308
|
+
const year = date.getUTCFullYear();
|
|
309
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
|
310
|
+
return `${year}-${month}`;
|
|
311
|
+
}
|
|
312
|
+
monthLabel(date) {
|
|
313
|
+
return date.toLocaleDateString('pt-BR', {
|
|
314
|
+
month: 'short',
|
|
315
|
+
year: '2-digit',
|
|
316
|
+
timeZone: 'UTC',
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
buildLicenseTimeline(studentRows, eventRows, start, end) {
|
|
320
|
+
const eventsByPerson = new Set(eventRows
|
|
321
|
+
.filter((event) => event.event_type === 'assigned')
|
|
322
|
+
.map((event) => event.person_id));
|
|
323
|
+
const syntheticEvents = studentRows
|
|
324
|
+
.filter((student) => !eventsByPerson.has(student.person_id))
|
|
325
|
+
.map((student) => ({
|
|
326
|
+
person_id: student.person_id,
|
|
327
|
+
event_type: 'assigned',
|
|
328
|
+
previous_status: null,
|
|
329
|
+
next_status: 'active',
|
|
330
|
+
created_at: student.created_at,
|
|
331
|
+
}));
|
|
332
|
+
const allEvents = [...eventRows, ...syntheticEvents].sort((a, b) => a.created_at.getTime() - b.created_at.getTime());
|
|
333
|
+
let running = 0;
|
|
334
|
+
for (const event of allEvents) {
|
|
335
|
+
if (event.created_at >= start)
|
|
336
|
+
break;
|
|
337
|
+
running += this.getLicenseEventDelta(event);
|
|
338
|
+
running = Math.max(running, 0);
|
|
339
|
+
}
|
|
340
|
+
const points = [];
|
|
341
|
+
const cursor = new Date(Date.UTC(start.getUTCFullYear(), start.getUTCMonth(), 1));
|
|
342
|
+
while (cursor <= end) {
|
|
343
|
+
const key = this.monthKey(cursor);
|
|
344
|
+
const monthEvents = allEvents.filter((event) => this.monthKey(event.created_at) === key);
|
|
345
|
+
const assigned = monthEvents.filter((event) => this.getLicenseEventDelta(event) > 0).length;
|
|
346
|
+
const revoked = monthEvents.filter((event) => this.getLicenseEventDelta(event) < 0).length;
|
|
347
|
+
for (const event of monthEvents) {
|
|
348
|
+
running += this.getLicenseEventDelta(event);
|
|
349
|
+
running = Math.max(running, 0);
|
|
350
|
+
}
|
|
351
|
+
points.push({
|
|
352
|
+
period: key,
|
|
353
|
+
label: this.monthLabel(cursor),
|
|
354
|
+
used: running,
|
|
355
|
+
assigned,
|
|
356
|
+
revoked,
|
|
357
|
+
});
|
|
358
|
+
cursor.setUTCMonth(cursor.getUTCMonth() + 1);
|
|
359
|
+
}
|
|
360
|
+
return points;
|
|
361
|
+
}
|
|
362
|
+
getLicenseEventDelta(event) {
|
|
363
|
+
if (event.event_type === 'assigned')
|
|
364
|
+
return 1;
|
|
365
|
+
if (event.event_type === 'revoked')
|
|
366
|
+
return -1;
|
|
367
|
+
if (event.event_type === 'status_changed') {
|
|
368
|
+
const wasActive = event.previous_status !== 'inactive';
|
|
369
|
+
const isActive = event.next_status !== 'inactive';
|
|
370
|
+
if (!wasActive && isActive)
|
|
371
|
+
return 1;
|
|
372
|
+
if (wasActive && !isActive)
|
|
373
|
+
return -1;
|
|
374
|
+
}
|
|
375
|
+
return 0;
|
|
376
|
+
}
|
|
377
|
+
buildEnterpriseActivities(licenseEvents, courses, classes, students, admins) {
|
|
378
|
+
return [
|
|
379
|
+
...licenseEvents.slice(-10).map((event) => {
|
|
380
|
+
var _a, _b, _c, _d;
|
|
381
|
+
return ({
|
|
382
|
+
id: `license-${(_b = (_a = event.person) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 'unknown'}-${event.created_at.getTime()}`,
|
|
383
|
+
type: event.event_type,
|
|
384
|
+
title: event.event_type === 'revoked'
|
|
385
|
+
? 'Licenca removida'
|
|
386
|
+
: 'Licenca atribuida',
|
|
387
|
+
description: (_d = (_c = event.person) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : 'Aluno',
|
|
388
|
+
createdAt: event.created_at,
|
|
389
|
+
});
|
|
390
|
+
}),
|
|
391
|
+
...courses.map((row) => {
|
|
392
|
+
var _a, _b, _c, _d;
|
|
393
|
+
return ({
|
|
394
|
+
id: `course-${(_b = (_a = row.course) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 'unknown'}-${row.created_at.getTime()}`,
|
|
395
|
+
type: 'course',
|
|
396
|
+
title: 'Curso vinculado',
|
|
397
|
+
description: (_d = (_c = row.course) === null || _c === void 0 ? void 0 : _c.title) !== null && _d !== void 0 ? _d : 'Curso',
|
|
398
|
+
createdAt: row.created_at,
|
|
399
|
+
});
|
|
400
|
+
}),
|
|
401
|
+
...classes.map((row) => {
|
|
402
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
403
|
+
return ({
|
|
404
|
+
id: `class-${(_b = (_a = row.course_class_group) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 'unknown'}-${row.created_at.getTime()}`,
|
|
405
|
+
type: 'class',
|
|
406
|
+
title: 'Turma vinculada',
|
|
407
|
+
description: (_j = (_f = (_d = (_c = row.course_class_group) === null || _c === void 0 ? void 0 : _c.code) !== null && _d !== void 0 ? _d : (_e = row.course_class_group) === null || _e === void 0 ? void 0 : _e.title) !== null && _f !== void 0 ? _f : (_h = (_g = row.course_class_group) === null || _g === void 0 ? void 0 : _g.course) === null || _h === void 0 ? void 0 : _h.title) !== null && _j !== void 0 ? _j : 'Turma',
|
|
408
|
+
createdAt: row.created_at,
|
|
409
|
+
});
|
|
410
|
+
}),
|
|
411
|
+
...students.map((row) => {
|
|
412
|
+
var _a, _b, _c, _d;
|
|
413
|
+
return ({
|
|
414
|
+
id: `student-${(_b = (_a = row.person) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 'unknown'}-${row.created_at.getTime()}`,
|
|
415
|
+
type: 'student',
|
|
416
|
+
title: 'Aluno adicionado',
|
|
417
|
+
description: (_d = (_c = row.person) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : 'Aluno',
|
|
418
|
+
createdAt: row.created_at,
|
|
419
|
+
});
|
|
420
|
+
}),
|
|
421
|
+
...admins.map((row) => {
|
|
422
|
+
var _a, _b, _c;
|
|
423
|
+
return ({
|
|
424
|
+
id: `admin-${(_b = (_a = row.user) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 'unknown'}-${row.created_at.getTime()}`,
|
|
425
|
+
type: 'admin',
|
|
426
|
+
title: 'Administrador adicionado',
|
|
427
|
+
description: ((_c = row.user) === null || _c === void 0 ? void 0 : _c.name) ? `${row.user.name} (${row.role})` : row.role,
|
|
428
|
+
createdAt: row.created_at,
|
|
429
|
+
});
|
|
430
|
+
}),
|
|
431
|
+
]
|
|
432
|
+
.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
|
|
433
|
+
.slice(0, 12);
|
|
434
|
+
}
|
|
152
435
|
async resolveRoleId(slug) {
|
|
153
436
|
var _a;
|
|
154
437
|
const role = await this.prisma.role.findUnique({
|
|
@@ -218,6 +501,7 @@ let EnterpriseService = class EnterpriseService {
|
|
|
218
501
|
id: true,
|
|
219
502
|
name: true,
|
|
220
503
|
last_login_at: true,
|
|
504
|
+
photo_id: true,
|
|
221
505
|
user_identifier: {
|
|
222
506
|
where: { type: 'email' },
|
|
223
507
|
select: { value: true },
|
|
@@ -235,16 +519,17 @@ let EnterpriseService = class EnterpriseService {
|
|
|
235
519
|
pageSize,
|
|
236
520
|
lastPage: Math.max(1, Math.ceil(total / pageSize)),
|
|
237
521
|
data: rows.map((r) => {
|
|
238
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
522
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
239
523
|
return ({
|
|
240
524
|
id: r.id,
|
|
241
525
|
userId: r.user_id,
|
|
242
526
|
personId: r.person_id,
|
|
243
527
|
name: (_b = (_a = r.user) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : null,
|
|
244
528
|
email: (_f = (_e = (_d = (_c = r.user) === null || _c === void 0 ? void 0 : _c.user_identifier) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : null,
|
|
529
|
+
photoId: (_h = (_g = r.user) === null || _g === void 0 ? void 0 : _g.photo_id) !== null && _h !== void 0 ? _h : null,
|
|
245
530
|
role: r.role,
|
|
246
531
|
status: r.status,
|
|
247
|
-
lastAccessAt: (
|
|
532
|
+
lastAccessAt: (_k = (_j = r.user) === null || _j === void 0 ? void 0 : _j.last_login_at) !== null && _k !== void 0 ? _k : null,
|
|
248
533
|
});
|
|
249
534
|
}),
|
|
250
535
|
};
|
|
@@ -336,6 +621,16 @@ let EnterpriseService = class EnterpriseService {
|
|
|
336
621
|
status: true,
|
|
337
622
|
level: true,
|
|
338
623
|
offering_type: true,
|
|
624
|
+
course_image: {
|
|
625
|
+
where: { image_type: { slug: 'course-logo' } },
|
|
626
|
+
take: 1,
|
|
627
|
+
select: {
|
|
628
|
+
file_id: true,
|
|
629
|
+
file: {
|
|
630
|
+
select: { id: true },
|
|
631
|
+
},
|
|
632
|
+
},
|
|
633
|
+
},
|
|
339
634
|
},
|
|
340
635
|
},
|
|
341
636
|
},
|
|
@@ -348,17 +643,19 @@ let EnterpriseService = class EnterpriseService {
|
|
|
348
643
|
pageSize,
|
|
349
644
|
lastPage: Math.max(1, Math.ceil(total / pageSize)),
|
|
350
645
|
data: rows.map((r) => {
|
|
351
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
352
|
-
|
|
646
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
647
|
+
const courseLogo = (_c = (_b = (_a = r.course) === null || _a === void 0 ? void 0 : _a.course_image) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : null;
|
|
648
|
+
return {
|
|
353
649
|
id: r.id,
|
|
354
650
|
courseId: r.course_id,
|
|
355
651
|
contractedAt: r.contracted_at,
|
|
356
|
-
title: (
|
|
357
|
-
slug: (
|
|
358
|
-
status: (
|
|
359
|
-
level: (
|
|
360
|
-
modality: (
|
|
361
|
-
|
|
652
|
+
title: (_e = (_d = r.course) === null || _d === void 0 ? void 0 : _d.title) !== null && _e !== void 0 ? _e : null,
|
|
653
|
+
slug: (_g = (_f = r.course) === null || _f === void 0 ? void 0 : _f.slug) !== null && _g !== void 0 ? _g : null,
|
|
654
|
+
status: (_j = (_h = r.course) === null || _h === void 0 ? void 0 : _h.status) !== null && _j !== void 0 ? _j : null,
|
|
655
|
+
level: (_l = (_k = r.course) === null || _k === void 0 ? void 0 : _k.level) !== null && _l !== void 0 ? _l : null,
|
|
656
|
+
modality: (_o = (_m = r.course) === null || _m === void 0 ? void 0 : _m.offering_type) !== null && _o !== void 0 ? _o : null,
|
|
657
|
+
logoFileId: (_r = (_q = (_p = courseLogo === null || courseLogo === void 0 ? void 0 : courseLogo.file) === null || _p === void 0 ? void 0 : _p.id) !== null && _q !== void 0 ? _q : courseLogo === null || courseLogo === void 0 ? void 0 : courseLogo.file_id) !== null && _r !== void 0 ? _r : null,
|
|
658
|
+
};
|
|
362
659
|
}),
|
|
363
660
|
};
|
|
364
661
|
}
|
|
@@ -425,7 +722,43 @@ let EnterpriseService = class EnterpriseService {
|
|
|
425
722
|
start_date: true,
|
|
426
723
|
end_date: true,
|
|
427
724
|
capacity: true,
|
|
428
|
-
|
|
725
|
+
_count: {
|
|
726
|
+
select: {
|
|
727
|
+
course_enrollment: {
|
|
728
|
+
where: {
|
|
729
|
+
status: { not: 'cancelled' },
|
|
730
|
+
},
|
|
731
|
+
},
|
|
732
|
+
},
|
|
733
|
+
},
|
|
734
|
+
instructor: {
|
|
735
|
+
select: {
|
|
736
|
+
id: true,
|
|
737
|
+
person: {
|
|
738
|
+
select: {
|
|
739
|
+
name: true,
|
|
740
|
+
avatar_id: true,
|
|
741
|
+
},
|
|
742
|
+
},
|
|
743
|
+
},
|
|
744
|
+
},
|
|
745
|
+
course: {
|
|
746
|
+
select: {
|
|
747
|
+
id: true,
|
|
748
|
+
title: true,
|
|
749
|
+
slug: true,
|
|
750
|
+
course_image: {
|
|
751
|
+
where: { image_type: { slug: 'course-logo' } },
|
|
752
|
+
take: 1,
|
|
753
|
+
select: {
|
|
754
|
+
file_id: true,
|
|
755
|
+
file: {
|
|
756
|
+
select: { id: true },
|
|
757
|
+
},
|
|
758
|
+
},
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
},
|
|
429
762
|
},
|
|
430
763
|
},
|
|
431
764
|
},
|
|
@@ -438,20 +771,26 @@ let EnterpriseService = class EnterpriseService {
|
|
|
438
771
|
pageSize,
|
|
439
772
|
lastPage: Math.max(1, Math.ceil(total / pageSize)),
|
|
440
773
|
data: rows.map((r) => {
|
|
441
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
442
|
-
|
|
774
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16;
|
|
775
|
+
const courseLogo = (_d = (_c = (_b = (_a = r.course_class_group) === null || _a === void 0 ? void 0 : _a.course) === null || _b === void 0 ? void 0 : _b.course_image) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : null;
|
|
776
|
+
return {
|
|
443
777
|
id: r.id,
|
|
444
778
|
courseClassGroupId: r.course_class_group_id,
|
|
445
|
-
code: (
|
|
446
|
-
title: (
|
|
447
|
-
status: (
|
|
448
|
-
deliveryMode: (
|
|
449
|
-
startDate: (
|
|
450
|
-
endDate: (
|
|
451
|
-
capacity: (
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
779
|
+
code: (_f = (_e = r.course_class_group) === null || _e === void 0 ? void 0 : _e.code) !== null && _f !== void 0 ? _f : null,
|
|
780
|
+
title: (_h = (_g = r.course_class_group) === null || _g === void 0 ? void 0 : _g.title) !== null && _h !== void 0 ? _h : null,
|
|
781
|
+
status: (_k = (_j = r.course_class_group) === null || _j === void 0 ? void 0 : _j.status) !== null && _k !== void 0 ? _k : null,
|
|
782
|
+
deliveryMode: (_m = (_l = r.course_class_group) === null || _l === void 0 ? void 0 : _l.delivery_mode) !== null && _m !== void 0 ? _m : null,
|
|
783
|
+
startDate: (_p = (_o = r.course_class_group) === null || _o === void 0 ? void 0 : _o.start_date) !== null && _p !== void 0 ? _p : null,
|
|
784
|
+
endDate: (_r = (_q = r.course_class_group) === null || _q === void 0 ? void 0 : _q.end_date) !== null && _r !== void 0 ? _r : null,
|
|
785
|
+
capacity: (_t = (_s = r.course_class_group) === null || _s === void 0 ? void 0 : _s.capacity) !== null && _t !== void 0 ? _t : null,
|
|
786
|
+
enrolledCount: (_w = (_v = (_u = r.course_class_group) === null || _u === void 0 ? void 0 : _u._count) === null || _v === void 0 ? void 0 : _v.course_enrollment) !== null && _w !== void 0 ? _w : 0,
|
|
787
|
+
instructorId: (_z = (_y = (_x = r.course_class_group) === null || _x === void 0 ? void 0 : _x.instructor) === null || _y === void 0 ? void 0 : _y.id) !== null && _z !== void 0 ? _z : null,
|
|
788
|
+
instructorName: (_3 = (_2 = (_1 = (_0 = r.course_class_group) === null || _0 === void 0 ? void 0 : _0.instructor) === null || _1 === void 0 ? void 0 : _1.person) === null || _2 === void 0 ? void 0 : _2.name) !== null && _3 !== void 0 ? _3 : null,
|
|
789
|
+
instructorAvatarId: (_7 = (_6 = (_5 = (_4 = r.course_class_group) === null || _4 === void 0 ? void 0 : _4.instructor) === null || _5 === void 0 ? void 0 : _5.person) === null || _6 === void 0 ? void 0 : _6.avatar_id) !== null && _7 !== void 0 ? _7 : null,
|
|
790
|
+
courseTitle: (_10 = (_9 = (_8 = r.course_class_group) === null || _8 === void 0 ? void 0 : _8.course) === null || _9 === void 0 ? void 0 : _9.title) !== null && _10 !== void 0 ? _10 : null,
|
|
791
|
+
courseSlug: (_13 = (_12 = (_11 = r.course_class_group) === null || _11 === void 0 ? void 0 : _11.course) === null || _12 === void 0 ? void 0 : _12.slug) !== null && _13 !== void 0 ? _13 : null,
|
|
792
|
+
logoFileId: (_16 = (_15 = (_14 = courseLogo === null || courseLogo === void 0 ? void 0 : courseLogo.file) === null || _14 === void 0 ? void 0 : _14.id) !== null && _15 !== void 0 ? _15 : courseLogo === null || courseLogo === void 0 ? void 0 : courseLogo.file_id) !== null && _16 !== void 0 ? _16 : null,
|
|
793
|
+
};
|
|
455
794
|
}),
|
|
456
795
|
};
|
|
457
796
|
}
|
|
@@ -490,6 +829,12 @@ let EnterpriseService = class EnterpriseService {
|
|
|
490
829
|
await this.prisma.enterprise_student.create({
|
|
491
830
|
data: { enterprise_id: enterpriseId, person_id, status: 'active' },
|
|
492
831
|
});
|
|
832
|
+
await this.recordLicenseEvent({
|
|
833
|
+
enterpriseId,
|
|
834
|
+
personId: person_id,
|
|
835
|
+
eventType: 'assigned',
|
|
836
|
+
nextStatus: 'active',
|
|
837
|
+
});
|
|
493
838
|
}
|
|
494
839
|
}
|
|
495
840
|
return link;
|
|
@@ -531,6 +876,7 @@ let EnterpriseService = class EnterpriseService {
|
|
|
531
876
|
select: {
|
|
532
877
|
id: true,
|
|
533
878
|
name: true,
|
|
879
|
+
avatar_id: true,
|
|
534
880
|
contact: {
|
|
535
881
|
where: { contact_type: { code: 'EMAIL' }, is_primary: true },
|
|
536
882
|
select: { value: true },
|
|
@@ -548,12 +894,13 @@ let EnterpriseService = class EnterpriseService {
|
|
|
548
894
|
pageSize,
|
|
549
895
|
lastPage: Math.max(1, Math.ceil(total / pageSize)),
|
|
550
896
|
data: rows.map((r) => {
|
|
551
|
-
var _a, _b, _c, _d, _e, _f;
|
|
897
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
552
898
|
return ({
|
|
553
899
|
id: r.id,
|
|
554
900
|
personId: r.person_id,
|
|
555
901
|
name: (_b = (_a = r.person) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : null,
|
|
556
902
|
email: (_f = (_e = (_d = (_c = r.person) === null || _c === void 0 ? void 0 : _c.contact) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : null,
|
|
903
|
+
avatarId: (_h = (_g = r.person) === null || _g === void 0 ? void 0 : _g.avatar_id) !== null && _h !== void 0 ? _h : null,
|
|
557
904
|
status: r.status,
|
|
558
905
|
createdAt: r.created_at,
|
|
559
906
|
});
|
|
@@ -561,6 +908,7 @@ let EnterpriseService = class EnterpriseService {
|
|
|
561
908
|
};
|
|
562
909
|
}
|
|
563
910
|
async addStudent(enterpriseId, dto) {
|
|
911
|
+
var _a;
|
|
564
912
|
await this.assertEnterpriseExists(enterpriseId);
|
|
565
913
|
const person = await this.prisma.person.findUnique({
|
|
566
914
|
where: { id: dto.person_id },
|
|
@@ -574,34 +922,58 @@ let EnterpriseService = class EnterpriseService {
|
|
|
574
922
|
});
|
|
575
923
|
if (duplicate)
|
|
576
924
|
throw new common_1.ConflictException(`Person #${dto.person_id} is already a student of enterprise #${enterpriseId}`);
|
|
577
|
-
|
|
925
|
+
const created = await this.prisma.enterprise_student.create({
|
|
578
926
|
data: Object.assign({ enterprise_id: enterpriseId }, dto),
|
|
579
927
|
});
|
|
928
|
+
await this.recordLicenseEvent({
|
|
929
|
+
enterpriseId,
|
|
930
|
+
personId: dto.person_id,
|
|
931
|
+
eventType: 'assigned',
|
|
932
|
+
nextStatus: (_a = dto.status) !== null && _a !== void 0 ? _a : 'pending',
|
|
933
|
+
});
|
|
934
|
+
return created;
|
|
580
935
|
}
|
|
581
936
|
async updateStudent(enterpriseId, personId, dto) {
|
|
582
937
|
await this.assertEnterpriseExists(enterpriseId);
|
|
583
938
|
const existing = await this.prisma.enterprise_student.findFirst({
|
|
584
939
|
where: { enterprise_id: enterpriseId, person_id: personId },
|
|
585
|
-
select: { id: true },
|
|
940
|
+
select: { id: true, status: true },
|
|
586
941
|
});
|
|
587
942
|
if (!existing)
|
|
588
943
|
throw new common_1.NotFoundException(`Person #${personId} is not a student of enterprise #${enterpriseId}`);
|
|
589
|
-
|
|
944
|
+
const updated = await this.prisma.enterprise_student.update({
|
|
590
945
|
where: { id: existing.id },
|
|
591
946
|
data: dto,
|
|
592
947
|
});
|
|
948
|
+
if (dto.status && dto.status !== existing.status) {
|
|
949
|
+
await this.recordLicenseEvent({
|
|
950
|
+
enterpriseId,
|
|
951
|
+
personId,
|
|
952
|
+
eventType: 'status_changed',
|
|
953
|
+
previousStatus: existing.status,
|
|
954
|
+
nextStatus: dto.status,
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
return updated;
|
|
593
958
|
}
|
|
594
959
|
async removeStudent(enterpriseId, personId) {
|
|
595
960
|
await this.assertEnterpriseExists(enterpriseId);
|
|
596
961
|
const existing = await this.prisma.enterprise_student.findFirst({
|
|
597
962
|
where: { enterprise_id: enterpriseId, person_id: personId },
|
|
598
|
-
select: { id: true },
|
|
963
|
+
select: { id: true, status: true },
|
|
599
964
|
});
|
|
600
965
|
if (!existing)
|
|
601
966
|
throw new common_1.NotFoundException(`Person #${personId} is not a student of enterprise #${enterpriseId}`);
|
|
602
|
-
|
|
967
|
+
const deleted = await this.prisma.enterprise_student.delete({
|
|
603
968
|
where: { id: existing.id },
|
|
604
969
|
});
|
|
970
|
+
await this.recordLicenseEvent({
|
|
971
|
+
enterpriseId,
|
|
972
|
+
personId,
|
|
973
|
+
eventType: 'revoked',
|
|
974
|
+
previousStatus: existing.status,
|
|
975
|
+
});
|
|
976
|
+
return deleted;
|
|
605
977
|
}
|
|
606
978
|
// ─── Stats / options ──────────────────────────────────────────────────────────
|
|
607
979
|
async getStats() {
|
|
@@ -795,7 +1167,7 @@ let EnterpriseService = class EnterpriseService {
|
|
|
795
1167
|
return profiles;
|
|
796
1168
|
}
|
|
797
1169
|
mapEnterprise(e, extra) {
|
|
798
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
1170
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
799
1171
|
const { _count, person } = e;
|
|
800
1172
|
const pc = (_a = extra === null || extra === void 0 ? void 0 : extra.personCompany) !== null && _a !== void 0 ? _a : null;
|
|
801
1173
|
return {
|
|
@@ -814,18 +1186,19 @@ let EnterpriseService = class EnterpriseService {
|
|
|
814
1186
|
? {
|
|
815
1187
|
id: person.id,
|
|
816
1188
|
name: person.name,
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
1189
|
+
avatarId: (_f = person.avatar_id) !== null && _f !== void 0 ? _f : null,
|
|
1190
|
+
tradeName: (_g = pc === null || pc === void 0 ? void 0 : pc.trade_name) !== null && _g !== void 0 ? _g : null,
|
|
1191
|
+
industry: (_h = pc === null || pc === void 0 ? void 0 : pc.industry) !== null && _h !== void 0 ? _h : null,
|
|
1192
|
+
website: (_j = pc === null || pc === void 0 ? void 0 : pc.website) !== null && _j !== void 0 ? _j : null,
|
|
1193
|
+
lifecycleStage: (_k = pc === null || pc === void 0 ? void 0 : pc.account_lifecycle_stage) !== null && _k !== void 0 ? _k : null,
|
|
821
1194
|
}
|
|
822
1195
|
: null,
|
|
823
|
-
usersCount: (
|
|
824
|
-
studentsCount: (
|
|
825
|
-
managersCount: (
|
|
826
|
-
adminsCount: (
|
|
827
|
-
coursesCount: (
|
|
828
|
-
classesCount: (
|
|
1196
|
+
usersCount: (_l = _count === null || _count === void 0 ? void 0 : _count.enterprise_user) !== null && _l !== void 0 ? _l : 0,
|
|
1197
|
+
studentsCount: (_m = extra === null || extra === void 0 ? void 0 : extra.studentsCount) !== null && _m !== void 0 ? _m : 0,
|
|
1198
|
+
managersCount: (_o = extra === null || extra === void 0 ? void 0 : extra.managersCount) !== null && _o !== void 0 ? _o : 0,
|
|
1199
|
+
adminsCount: (_p = extra === null || extra === void 0 ? void 0 : extra.adminsCount) !== null && _p !== void 0 ? _p : 0,
|
|
1200
|
+
coursesCount: (_q = _count === null || _count === void 0 ? void 0 : _count.enterprise_course) !== null && _q !== void 0 ? _q : 0,
|
|
1201
|
+
classesCount: (_r = _count === null || _count === void 0 ? void 0 : _count.enterprise_class_group) !== null && _r !== void 0 ? _r : 0,
|
|
829
1202
|
};
|
|
830
1203
|
}
|
|
831
1204
|
};
|