@hed-hog/lms 0.0.270 → 0.0.275
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/README.md +602 -0
- package/package.json +8 -8
package/README.md
ADDED
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
```markdown
|
|
2
|
+
# @hed-hog/lms
|
|
3
|
+
|
|
4
|
+
## 1. Visão geral do módulo
|
|
5
|
+
|
|
6
|
+
O módulo `@hed-hog/lms` é responsável pela gestão do sistema de Learning Management System (LMS) dentro do monorepo HedHog. Ele oferece funcionalidades para gerenciamento de cursos, aulas, avaliações, certificados, matrículas, instrutores, trilhas de aprendizagem e demais componentes relacionados ao ambiente educacional digital.
|
|
7
|
+
|
|
8
|
+
## 2. Escopo e responsabilidades
|
|
9
|
+
|
|
10
|
+
- Gerenciamento de cursos, módulos, aulas e suas respectivas estruturas.
|
|
11
|
+
- Controle de matrículas em cursos e trilhas de aprendizagem.
|
|
12
|
+
- Administração de avaliações, tentativas e respostas.
|
|
13
|
+
- Emissão e verificação de certificados.
|
|
14
|
+
- Gestão de instrutores e suas atribuições.
|
|
15
|
+
- Controle de presenças em aulas presenciais ou online.
|
|
16
|
+
- Organização de trilhas de aprendizagem e seus passos.
|
|
17
|
+
- Suporte a imagens e arquivos relacionados a cursos, exames e trilhas.
|
|
18
|
+
- Avaliações e feedbacks sobre tópicos específicos do LMS.
|
|
19
|
+
|
|
20
|
+
## 3. Endpoints
|
|
21
|
+
|
|
22
|
+
> **Nota:** O código fonte fornecido não expõe endpoints REST ou GraphQL diretamente. Este módulo é consumido via serviços internos ou APIs do HedHog que integram com o LMS.
|
|
23
|
+
|
|
24
|
+
## 4. Regras de autenticação e autorização
|
|
25
|
+
|
|
26
|
+
- Existe o papel (`role`) `admin-lms` com permissão total para gestão do LMS.
|
|
27
|
+
- Autenticação e autorização são gerenciadas externamente, utilizando o papel `admin-lms` para operações administrativas.
|
|
28
|
+
- Regras específicas de acesso devem ser implementadas conforme a integração com o sistema de autenticação do HedHog.
|
|
29
|
+
|
|
30
|
+
## 5. Estruturas de request/response
|
|
31
|
+
|
|
32
|
+
- Não aplicável diretamente, pois o módulo não expõe endpoints REST no código fornecido.
|
|
33
|
+
- Operações são realizadas via serviços internos ou APIs que consomem este módulo.
|
|
34
|
+
|
|
35
|
+
## 6. Erros comuns
|
|
36
|
+
|
|
37
|
+
- **Violação de integridade referencial:** ao inserir ou atualizar registros com chaves estrangeiras inválidas.
|
|
38
|
+
- **Duplicidade de registros únicos:** como códigos únicos de certificado, slugs de cursos ou templates.
|
|
39
|
+
- **Status inválidos:** ao definir valores fora dos enums para status de cursos, exames, matrículas, etc.
|
|
40
|
+
- **Campos obrigatórios ausentes:** como títulos, slugs e chaves primárias.
|
|
41
|
+
|
|
42
|
+
## 7. Banco de dados (tabelas YAML)
|
|
43
|
+
|
|
44
|
+
### certificate
|
|
45
|
+
|
|
46
|
+
- **Finalidade:** Armazena certificados emitidos para estudantes em cursos, exames, grupos de aulas ou trilhas de aprendizagem.
|
|
47
|
+
- **Colunas:**
|
|
48
|
+
- `id` (PK)
|
|
49
|
+
- `verification_code` (varchar 50, único): código para verificação do certificado.
|
|
50
|
+
- `student_id` (FK para `person.id`, onDelete CASCADE): estudante que recebeu o certificado.
|
|
51
|
+
- `course_enrollment_id` (FK opcional para `course_enrollment.id`, onDelete SET NULL)
|
|
52
|
+
- `course_id` (FK opcional para `course.id`, onDelete SET NULL)
|
|
53
|
+
- `exam_id` (FK opcional para `exam.id`, onDelete SET NULL)
|
|
54
|
+
- `course_class_group_id` (FK opcional para `course_class_group.id`, onDelete SET NULL)
|
|
55
|
+
- `learning_path_id` (FK opcional para `learning_path.id`, onDelete SET NULL)
|
|
56
|
+
- `certificate_template_id` (FK para `certificate_template.id`)
|
|
57
|
+
- `certificate_type` (enum: `course`, `exam`, `course_class_group`, `learning_path`)
|
|
58
|
+
- `student_name` (varchar 255)
|
|
59
|
+
- `course_name` (varchar 255)
|
|
60
|
+
- `workload_hours` (int)
|
|
61
|
+
- `issued_at` (datetime)
|
|
62
|
+
- `completed_at` (datetime)
|
|
63
|
+
- `final_score` (int, nullable)
|
|
64
|
+
- `verification_url` (varchar 500, nullable)
|
|
65
|
+
- `pdf_url` (varchar 500, nullable)
|
|
66
|
+
- `created_at`, `updated_at`
|
|
67
|
+
- **Índices:** único em `verification_code`.
|
|
68
|
+
|
|
69
|
+
### certificate_template
|
|
70
|
+
|
|
71
|
+
- **Finalidade:** Modelos de certificados para emissão.
|
|
72
|
+
- **Colunas:**
|
|
73
|
+
- `id` (PK)
|
|
74
|
+
- `name` (varchar 255)
|
|
75
|
+
- `slug` (varchar 255, único)
|
|
76
|
+
- `description` (text, nullable)
|
|
77
|
+
- `template_content` (text)
|
|
78
|
+
- `status` (enum: `draft`, `active`, `inactive`, default `draft`)
|
|
79
|
+
- `created_at`, `updated_at`
|
|
80
|
+
- **Índices:** único em `slug`.
|
|
81
|
+
|
|
82
|
+
### course
|
|
83
|
+
|
|
84
|
+
- **Finalidade:** Cursos disponíveis no LMS.
|
|
85
|
+
- **Colunas:**
|
|
86
|
+
- `id` (PK)
|
|
87
|
+
- `title` (varchar 255)
|
|
88
|
+
- `slug` (varchar 255, único)
|
|
89
|
+
- `description` (text, nullable)
|
|
90
|
+
- `short_description` (varchar 500, nullable)
|
|
91
|
+
- `level` (enum: `beginner`, `intermediate`, `advanced`, default `beginner`)
|
|
92
|
+
- `duration_hours` (int, default 0)
|
|
93
|
+
- `status` (enum: `draft`, `published`, `archived`, default `draft`)
|
|
94
|
+
- `primary_color`, `primary_contrast_color`, `secondary_color`, `secondary_contrast_color` (varchar 9, nullable)
|
|
95
|
+
- `certificate_workload` (int, nullable)
|
|
96
|
+
- `certificate_template_id` (FK opcional para `certificate_template.id`, onDelete SET NULL)
|
|
97
|
+
- `requirements`, `objectives`, `target_audience` (text, nullable)
|
|
98
|
+
- `created_at`, `updated_at`
|
|
99
|
+
- **Índices:** único em `slug`.
|
|
100
|
+
|
|
101
|
+
### course_category
|
|
102
|
+
|
|
103
|
+
- **Finalidade:** Associação entre cursos e categorias.
|
|
104
|
+
- **Colunas:**
|
|
105
|
+
- `id` (PK)
|
|
106
|
+
- `course_id` (FK para `course.id`, onDelete CASCADE)
|
|
107
|
+
- `category_id` (FK para `category.id`, onDelete CASCADE)
|
|
108
|
+
- `created_at`, `updated_at`
|
|
109
|
+
- **Índices:** único em combinação `course_id` + `category_id`.
|
|
110
|
+
|
|
111
|
+
### course_class_attendance
|
|
112
|
+
|
|
113
|
+
- **Finalidade:** Registro de presença dos estudantes em sessões de aula.
|
|
114
|
+
- **Colunas:**
|
|
115
|
+
- `id` (PK)
|
|
116
|
+
- `course_class_session_id` (FK para `course_class_session.id`, onDelete CASCADE)
|
|
117
|
+
- `student_id` (FK para `person.id`, onDelete CASCADE)
|
|
118
|
+
- `present` (boolean, default false)
|
|
119
|
+
- `justification` (text, nullable)
|
|
120
|
+
- `recorded_by_id` (FK opcional para `person.id`, onDelete SET NULL)
|
|
121
|
+
- `created_at`, `updated_at`
|
|
122
|
+
- **Índices:** único em combinação `course_class_session_id` + `student_id`.
|
|
123
|
+
|
|
124
|
+
### course_class_group
|
|
125
|
+
|
|
126
|
+
- **Finalidade:** Grupos de aulas de um curso.
|
|
127
|
+
- **Colunas:**
|
|
128
|
+
- `id` (PK)
|
|
129
|
+
- `course_id` (FK para `course.id`, onDelete CASCADE)
|
|
130
|
+
- `title` (varchar 255)
|
|
131
|
+
- `code` (varchar 50, único)
|
|
132
|
+
- `description` (text, nullable)
|
|
133
|
+
- `delivery_mode` (enum: `presential`, `online`, `hybrid`)
|
|
134
|
+
- `status` (enum: `open`, `ongoing`, `completed`, `cancelled`, default `open`)
|
|
135
|
+
- `start_date` (datetime)
|
|
136
|
+
- `end_date` (datetime, nullable)
|
|
137
|
+
- `start_time` (varchar 5, nullable)
|
|
138
|
+
- `end_time` (varchar 5, nullable)
|
|
139
|
+
- `week_days` (text, nullable)
|
|
140
|
+
- `capacity` (int, default 30)
|
|
141
|
+
- `location` (text, nullable)
|
|
142
|
+
- `virtual_room_url` (varchar 500, nullable)
|
|
143
|
+
- `created_at`, `updated_at`
|
|
144
|
+
- **Índices:** único em `code`.
|
|
145
|
+
|
|
146
|
+
### course_class_session
|
|
147
|
+
|
|
148
|
+
- **Finalidade:** Sessões específicas dentro de um grupo de aula.
|
|
149
|
+
- **Colunas:**
|
|
150
|
+
- `id` (PK)
|
|
151
|
+
- `course_class_group_id` (FK para `course_class_group.id`, onDelete CASCADE)
|
|
152
|
+
- `title` (varchar 255)
|
|
153
|
+
- `description` (text, nullable)
|
|
154
|
+
- `session_date` (datetime)
|
|
155
|
+
- `start_time` (varchar 5)
|
|
156
|
+
- `end_time` (varchar 5)
|
|
157
|
+
- `location` (text, nullable)
|
|
158
|
+
- `meeting_url` (varchar 500, nullable)
|
|
159
|
+
- `status` (enum: `scheduled`, `completed`, `cancelled`, default `scheduled`)
|
|
160
|
+
- `created_at`, `updated_at`
|
|
161
|
+
- **Índices:** combinação `course_class_group_id` + `session_date`.
|
|
162
|
+
|
|
163
|
+
### course_class_session_instructor
|
|
164
|
+
|
|
165
|
+
- **Finalidade:** Instrutores vinculados a sessões de aula.
|
|
166
|
+
- **Colunas:**
|
|
167
|
+
- `id` (PK)
|
|
168
|
+
- `course_class_session_id` (FK para `course_class_session.id`, onDelete CASCADE)
|
|
169
|
+
- `instructor_id` (FK para `instructor.id`, onDelete CASCADE)
|
|
170
|
+
- `role` (enum: `lead`, `assistant`, default `assistant`)
|
|
171
|
+
- `created_at`, `updated_at`
|
|
172
|
+
- **Índices:** único em combinação `course_class_session_id` + `instructor_id`.
|
|
173
|
+
|
|
174
|
+
### course_enrollment
|
|
175
|
+
|
|
176
|
+
- **Finalidade:** Matrículas de pessoas em cursos ou grupos de aula.
|
|
177
|
+
- **Colunas:**
|
|
178
|
+
- `id` (PK)
|
|
179
|
+
- `person_id` (FK para `person.id`, onDelete CASCADE)
|
|
180
|
+
- `course_class_group_id` (FK opcional para `course_class_group.id`, onDelete SET NULL)
|
|
181
|
+
- `course_id` (FK para `course.id`, onDelete CASCADE)
|
|
182
|
+
- `status` (enum: `pending`, `active`, `completed`, `cancelled`, `paused`, default `active`)
|
|
183
|
+
- `enrolled_at` (datetime)
|
|
184
|
+
- `completed_at` (datetime, nullable)
|
|
185
|
+
- `progress_percent` (int, default 0)
|
|
186
|
+
- `final_score` (int, nullable)
|
|
187
|
+
- `created_at`, `updated_at`
|
|
188
|
+
- **Índices:** único em combinação `person_id` + `course_class_group_id`.
|
|
189
|
+
|
|
190
|
+
### course_image
|
|
191
|
+
|
|
192
|
+
- **Finalidade:** Imagens associadas a cursos.
|
|
193
|
+
- **Colunas:**
|
|
194
|
+
- `id` (PK)
|
|
195
|
+
- `course_id` (FK para `course.id`, onDelete CASCADE)
|
|
196
|
+
- `file_id` (FK para `file.id`, onDelete CASCADE)
|
|
197
|
+
- `image_type_id` (FK para `image_type.id`, onDelete CASCADE)
|
|
198
|
+
- `order` (int)
|
|
199
|
+
- `is_primary` (boolean, default false)
|
|
200
|
+
- `created_at`, `updated_at`
|
|
201
|
+
- **Índices:** único em combinação `course_id` + `image_type_id` + `order`.
|
|
202
|
+
|
|
203
|
+
### course_lesson
|
|
204
|
+
|
|
205
|
+
- **Finalidade:** Aulas dentro de módulos de curso.
|
|
206
|
+
- **Colunas:**
|
|
207
|
+
- `id` (PK)
|
|
208
|
+
- `course_module_id` (FK para `course_module.id`, onDelete CASCADE)
|
|
209
|
+
- `title` (varchar 255)
|
|
210
|
+
- `description` (text, nullable)
|
|
211
|
+
- `type` (enum: `video`, `text`, `quiz`, default `video`)
|
|
212
|
+
- `content` (text, nullable)
|
|
213
|
+
- `duration_seconds` (int, default 0)
|
|
214
|
+
- `order` (int)
|
|
215
|
+
- `is_released` (boolean, default true)
|
|
216
|
+
- `created_at`, `updated_at`
|
|
217
|
+
- **Índices:** único em combinação `course_module_id` + `order`.
|
|
218
|
+
|
|
219
|
+
### course_lesson_file
|
|
220
|
+
|
|
221
|
+
- **Finalidade:** Arquivos vinculados a aulas.
|
|
222
|
+
- **Colunas:**
|
|
223
|
+
- `id` (PK)
|
|
224
|
+
- `course_lesson_id` (FK para `course_lesson.id`, onDelete CASCADE)
|
|
225
|
+
- `file_id` (FK opcional para `file.id`, onDelete SET NULL)
|
|
226
|
+
- `title` (varchar 255)
|
|
227
|
+
- `created_at`, `updated_at`
|
|
228
|
+
- **Índices:** em `course_lesson_id`.
|
|
229
|
+
|
|
230
|
+
### course_lesson_instructor
|
|
231
|
+
|
|
232
|
+
- **Finalidade:** Instrutores vinculados a aulas.
|
|
233
|
+
- **Colunas:**
|
|
234
|
+
- `id` (PK)
|
|
235
|
+
- `course_lesson_id` (FK para `course_lesson.id`, onDelete CASCADE)
|
|
236
|
+
- `instructor_id` (FK para `instructor.id`, onDelete CASCADE)
|
|
237
|
+
- `role` (enum: `lead`, `assistant`, default `assistant`)
|
|
238
|
+
- `created_at`, `updated_at`
|
|
239
|
+
- **Índices:** único em combinação `course_lesson_id` + `instructor_id`.
|
|
240
|
+
|
|
241
|
+
### course_lesson_progress
|
|
242
|
+
|
|
243
|
+
- **Finalidade:** Progresso dos estudantes em aulas.
|
|
244
|
+
- **Colunas:**
|
|
245
|
+
- `id` (PK)
|
|
246
|
+
- `course_enrollment_id` (FK para `course_enrollment.id`, onDelete CASCADE)
|
|
247
|
+
- `course_lesson_id` (FK para `course_lesson.id`, onDelete CASCADE)
|
|
248
|
+
- `status` (enum: `not_started`, `in_progress`, `completed`, default `not_started`)
|
|
249
|
+
- `progress_percent` (int, default 0)
|
|
250
|
+
- `video_progress_seconds` (int, default 0)
|
|
251
|
+
- `started_at` (datetime, nullable)
|
|
252
|
+
- `completed_at` (datetime, nullable)
|
|
253
|
+
- `time_spent_seconds` (int, default 0)
|
|
254
|
+
- `created_at`, `updated_at`
|
|
255
|
+
- **Índices:** único em combinação `course_enrollment_id` + `course_lesson_id`.
|
|
256
|
+
|
|
257
|
+
### course_lesson_question
|
|
258
|
+
|
|
259
|
+
- **Finalidade:** Questões associadas a aulas do tipo quiz.
|
|
260
|
+
- **Colunas:**
|
|
261
|
+
- `id` (PK)
|
|
262
|
+
- `course_lesson_id` (FK para `course_lesson.id`, onDelete CASCADE)
|
|
263
|
+
- `question_id` (FK para `question.id`, onDelete CASCADE)
|
|
264
|
+
- `order` (int)
|
|
265
|
+
- `created_at`, `updated_at`
|
|
266
|
+
- **Índices:** únicos em combinações `course_lesson_id` + `question_id` e `course_lesson_id` + `order`.
|
|
267
|
+
|
|
268
|
+
### course_module
|
|
269
|
+
|
|
270
|
+
- **Finalidade:** Módulos dentro de cursos.
|
|
271
|
+
- **Colunas:**
|
|
272
|
+
- `id` (PK)
|
|
273
|
+
- `course_id` (FK para `course.id`, onDelete CASCADE)
|
|
274
|
+
- `title` (varchar 255)
|
|
275
|
+
- `description` (text, nullable)
|
|
276
|
+
- `order` (int)
|
|
277
|
+
- `duration_minutes` (int, default 0)
|
|
278
|
+
- `created_at`, `updated_at`
|
|
279
|
+
- **Índices:** único em combinação `course_id` + `order`.
|
|
280
|
+
|
|
281
|
+
### course_prerequisite
|
|
282
|
+
|
|
283
|
+
- **Finalidade:** Pré-requisitos para cursos.
|
|
284
|
+
- **Colunas:**
|
|
285
|
+
- `id` (PK)
|
|
286
|
+
- `course_id` (FK para `course.id`, onDelete CASCADE)
|
|
287
|
+
- `prerequisite_type` (enum: `course`, `learning_path`, `exam`, default `course`)
|
|
288
|
+
- `prerequisite_course_id` (FK opcional para `course.id`, onDelete CASCADE)
|
|
289
|
+
- `prerequisite_learning_path_id` (FK opcional para `learning_path.id`, onDelete CASCADE)
|
|
290
|
+
- `prerequisite_exam_id` (FK opcional para `exam.id`, onDelete CASCADE)
|
|
291
|
+
- `created_at`, `updated_at`
|
|
292
|
+
- **Índices:** únicos para combinações de curso e pré-requisitos.
|
|
293
|
+
|
|
294
|
+
### evaluation_rating
|
|
295
|
+
|
|
296
|
+
- **Finalidade:** Avaliações e notas dadas a tópicos de avaliação.
|
|
297
|
+
- **Colunas:**
|
|
298
|
+
- `id` (PK)
|
|
299
|
+
- `evaluation_topic_id` (FK para `evaluation_topic.id`, onDelete CASCADE)
|
|
300
|
+
- `evaluator_id` (FK opcional para `person.id`, onDelete SET NULL)
|
|
301
|
+
- `score` (decimal 2,1)
|
|
302
|
+
- `comment` (text, nullable)
|
|
303
|
+
- `created_at`, `updated_at`
|
|
304
|
+
- **Índices:** único em combinação `evaluation_topic_id` + `evaluator_id`.
|
|
305
|
+
|
|
306
|
+
### evaluation_topic
|
|
307
|
+
|
|
308
|
+
- **Finalidade:** Tópicos para avaliação dentro do LMS.
|
|
309
|
+
- **Colunas:**
|
|
310
|
+
- `id` (PK)
|
|
311
|
+
- `name` (varchar 255)
|
|
312
|
+
- `description` (text, nullable)
|
|
313
|
+
- `target_type` (enum: `course`, `course_lesson`, `course_class_session`, `question`, `exam`)
|
|
314
|
+
- `course_id` (FK opcional para `course.id`, onDelete SET NULL)
|
|
315
|
+
- `course_lesson_id` (FK opcional para `course_lesson.id`, onDelete SET NULL)
|
|
316
|
+
- `course_class_session_id` (FK opcional para `course_class_session.id`, onDelete SET NULL)
|
|
317
|
+
- `question_id` (FK opcional para `question.id`, onDelete SET NULL)
|
|
318
|
+
- `exam_id` (FK opcional para `exam.id`, onDelete SET NULL)
|
|
319
|
+
- `order` (int)
|
|
320
|
+
- `is_active` (boolean, default true)
|
|
321
|
+
- `created_at`, `updated_at`
|
|
322
|
+
- **Índices:** únicos para combinações de alvo e ordem.
|
|
323
|
+
|
|
324
|
+
### exam
|
|
325
|
+
|
|
326
|
+
- **Finalidade:** Exames vinculados a cursos ou grupos de aula.
|
|
327
|
+
- **Colunas:**
|
|
328
|
+
- `id` (PK)
|
|
329
|
+
- `course_id` (FK opcional para `course.id`, onDelete SET NULL)
|
|
330
|
+
- `course_class_group_id` (FK opcional para `course_class_group.id`, onDelete SET NULL)
|
|
331
|
+
- `title` (varchar 255)
|
|
332
|
+
- `description` (text, nullable)
|
|
333
|
+
- `instructions` (text, nullable)
|
|
334
|
+
- `exam_type` (enum: `quiz`, `test`, `assignment`, `project`)
|
|
335
|
+
- `status` (enum: `draft`, `published`, `closed`, `archived`, default `draft`)
|
|
336
|
+
- `primary_color`, `primary_contrast_color`, `secondary_color`, `secondary_contrast_color` (varchar 9, nullable)
|
|
337
|
+
- `starts_at` (datetime, nullable)
|
|
338
|
+
- `ends_at` (datetime, nullable)
|
|
339
|
+
- `time_limit_minutes` (int, nullable)
|
|
340
|
+
- `attempts_allowed` (int, default 1)
|
|
341
|
+
- `min_score` (int, default 60)
|
|
342
|
+
- `max_score` (int, default 100)
|
|
343
|
+
- `shuffle_questions` (boolean, default false)
|
|
344
|
+
- `shuffle_options` (boolean, default false)
|
|
345
|
+
- `show_result` (boolean, default true)
|
|
346
|
+
- `show_answer_key` (boolean, default false)
|
|
347
|
+
- `show_explanation_after_answer` (boolean, default false)
|
|
348
|
+
- `require_all_questions_answered_to_finish` (boolean, default false)
|
|
349
|
+
- `created_at`, `updated_at`
|
|
350
|
+
- **Índices:** em `course_id`, `course_class_group_id` e `status`.
|
|
351
|
+
|
|
352
|
+
### exam_answer
|
|
353
|
+
|
|
354
|
+
- **Finalidade:** Respostas dadas em tentativas de exame.
|
|
355
|
+
- **Colunas:**
|
|
356
|
+
- `id` (PK)
|
|
357
|
+
- `exam_attempt_id` (FK para `exam_attempt.id`, onDelete CASCADE)
|
|
358
|
+
- `question_id` (FK para `question.id`, onDelete CASCADE)
|
|
359
|
+
- `exam_option_id` (FK opcional para `exam_option.id`, onDelete SET NULL)
|
|
360
|
+
- `answer_text` (text, nullable)
|
|
361
|
+
- `is_correct` (boolean, nullable)
|
|
362
|
+
- `points_awarded` (int, default 0)
|
|
363
|
+
- `teacher_feedback` (text, nullable)
|
|
364
|
+
- `created_at`, `updated_at`
|
|
365
|
+
- **Índices:** único em combinação `exam_attempt_id` + `question_id`.
|
|
366
|
+
|
|
367
|
+
### exam_attempt
|
|
368
|
+
|
|
369
|
+
- **Finalidade:** Tentativas de realização de exames por estudantes.
|
|
370
|
+
- **Colunas:**
|
|
371
|
+
- `id` (PK)
|
|
372
|
+
- `exam_id` (FK para `exam.id`, onDelete CASCADE)
|
|
373
|
+
- `student_id` (FK para `person.id`, onDelete CASCADE)
|
|
374
|
+
- `course_enrollment_id` (FK opcional para `course_enrollment.id`, onDelete SET NULL)
|
|
375
|
+
- `attempt_number` (int, default 1)
|
|
376
|
+
- `started_at` (datetime)
|
|
377
|
+
- `finished_at` (datetime, nullable)
|
|
378
|
+
- `duration_seconds` (int, nullable)
|
|
379
|
+
- `score` (int, nullable)
|
|
380
|
+
- `status` (enum: `in_progress`, `completed`, `abandoned`, `voided`, default `in_progress`)
|
|
381
|
+
- `ip_address` (varchar 45, nullable)
|
|
382
|
+
- `created_at`, `updated_at`
|
|
383
|
+
- **Índices:** único em combinação `exam_id` + `student_id` + `attempt_number`.
|
|
384
|
+
|
|
385
|
+
### exam_image
|
|
386
|
+
|
|
387
|
+
- **Finalidade:** Imagens associadas a exames.
|
|
388
|
+
- **Colunas:**
|
|
389
|
+
- `id` (PK)
|
|
390
|
+
- `exam_id` (FK para `exam.id`, onDelete CASCADE)
|
|
391
|
+
- `file_id` (FK para `file.id`, onDelete CASCADE)
|
|
392
|
+
- `image_type_id` (FK para `image_type.id`, onDelete CASCADE)
|
|
393
|
+
- `order` (int)
|
|
394
|
+
- `is_primary` (boolean, default false)
|
|
395
|
+
- `created_at`, `updated_at`
|
|
396
|
+
- **Índices:** único em combinação `exam_id` + `image_type_id` + `order`.
|
|
397
|
+
|
|
398
|
+
### exam_option
|
|
399
|
+
|
|
400
|
+
- **Finalidade:** Opções de resposta para questões de exame.
|
|
401
|
+
- **Colunas:**
|
|
402
|
+
- `id` (PK)
|
|
403
|
+
- `question_id` (FK para `question.id`, onDelete CASCADE)
|
|
404
|
+
- `option_text` (text)
|
|
405
|
+
- `is_correct` (boolean, default false)
|
|
406
|
+
- `position` (int, default 0)
|
|
407
|
+
- `feedback` (text, nullable)
|
|
408
|
+
- `created_at`, `updated_at`
|
|
409
|
+
- **Índices:** único em combinação `question_id` + `position`.
|
|
410
|
+
|
|
411
|
+
### exam_question
|
|
412
|
+
|
|
413
|
+
- **Finalidade:** Questões associadas a exames.
|
|
414
|
+
- **Colunas:**
|
|
415
|
+
- `id` (PK)
|
|
416
|
+
- `exam_id` (FK para `exam.id`, onDelete CASCADE)
|
|
417
|
+
- `question_id` (FK para `question.id`, onDelete CASCADE)
|
|
418
|
+
- `order` (int)
|
|
419
|
+
- `created_at`, `updated_at`
|
|
420
|
+
- **Índices:** únicos em combinações `exam_id` + `question_id` e `exam_id` + `order`.
|
|
421
|
+
|
|
422
|
+
### image_type
|
|
423
|
+
|
|
424
|
+
- **Finalidade:** Tipos de imagens aplicáveis a cursos, exames e trilhas.
|
|
425
|
+
- **Colunas:**
|
|
426
|
+
- `id` (PK)
|
|
427
|
+
- `name` (varchar 100)
|
|
428
|
+
- `slug` (varchar 100, único)
|
|
429
|
+
- `applies_to_course` (boolean, default false)
|
|
430
|
+
- `applies_to_exam` (boolean, default false)
|
|
431
|
+
- `applies_to_learning_path` (boolean, default false)
|
|
432
|
+
- `status` (enum: `active`, `inactive`, default `active`)
|
|
433
|
+
- `created_at`, `updated_at`
|
|
434
|
+
- **Índices:** único em `slug`.
|
|
435
|
+
|
|
436
|
+
### instructor
|
|
437
|
+
|
|
438
|
+
- **Finalidade:** Instrutores cadastrados no LMS.
|
|
439
|
+
- **Colunas:**
|
|
440
|
+
- `id` (PK)
|
|
441
|
+
- `person_id` (FK único para `person.id`, onDelete CASCADE)
|
|
442
|
+
- `status` (enum: `active`, `inactive`, default `active`)
|
|
443
|
+
- `can_teach_courses` (boolean, default true)
|
|
444
|
+
- `created_at`, `updated_at`
|
|
445
|
+
- **Índices:** único em `person_id`.
|
|
446
|
+
|
|
447
|
+
### learning_path
|
|
448
|
+
|
|
449
|
+
- **Finalidade:** Trilhas de aprendizagem compostas por cursos e exames.
|
|
450
|
+
- **Colunas:**
|
|
451
|
+
- `id` (PK)
|
|
452
|
+
- `title` (varchar 255)
|
|
453
|
+
- `slug` (varchar 255, único)
|
|
454
|
+
- `description` (text, nullable)
|
|
455
|
+
- `short_description` (varchar 500, nullable)
|
|
456
|
+
- `level` (enum: `beginner`, `intermediate`, `advanced`, default `beginner`)
|
|
457
|
+
- `duration_hours` (int, default 0)
|
|
458
|
+
- `status` (enum: `draft`, `active`, `archived`, default `draft`)
|
|
459
|
+
- `primary_color`, `primary_contrast_color`, `secondary_color`, `secondary_contrast_color` (varchar 9, nullable)
|
|
460
|
+
- `created_at`, `updated_at`
|
|
461
|
+
- **Índices:** único em `slug`.
|
|
462
|
+
|
|
463
|
+
### learning_path_enrollment
|
|
464
|
+
|
|
465
|
+
- **Finalidade:** Matrículas em trilhas de aprendizagem.
|
|
466
|
+
- **Colunas:**
|
|
467
|
+
- `id` (PK)
|
|
468
|
+
- `learning_path_id` (FK para `learning_path.id`, onDelete CASCADE)
|
|
469
|
+
- `person_id` (FK para `person.id`, onDelete CASCADE)
|
|
470
|
+
- `status` (enum: `active`, `completed`, `cancelled`, default `active`)
|
|
471
|
+
- `progress_percent` (int, default 0)
|
|
472
|
+
- `enrolled_at` (datetime)
|
|
473
|
+
- `completed_at` (datetime, nullable)
|
|
474
|
+
- `created_at`, `updated_at`
|
|
475
|
+
- **Índices:** único em combinação `learning_path_id` + `person_id`.
|
|
476
|
+
|
|
477
|
+
### learning_path_image
|
|
478
|
+
|
|
479
|
+
- **Finalidade:** Imagens associadas a trilhas de aprendizagem.
|
|
480
|
+
- **Colunas:**
|
|
481
|
+
- `id` (PK)
|
|
482
|
+
- `learning_path_id` (FK para `learning_path.id`, onDelete CASCADE)
|
|
483
|
+
- `file_id` (FK para `file.id`, onDelete CASCADE)
|
|
484
|
+
- `image_type_id` (FK para `image_type.id`, onDelete CASCADE)
|
|
485
|
+
- `order` (int)
|
|
486
|
+
- `is_primary` (boolean, default false)
|
|
487
|
+
- `created_at`, `updated_at`
|
|
488
|
+
- **Índices:** único em combinação `learning_path_id` + `image_type_id` + `order`.
|
|
489
|
+
|
|
490
|
+
### learning_path_step
|
|
491
|
+
|
|
492
|
+
- **Finalidade:** Passos dentro de uma trilha, podendo ser cursos ou exames.
|
|
493
|
+
- **Colunas:**
|
|
494
|
+
- `id` (PK)
|
|
495
|
+
- `learning_path_id` (FK para `learning_path.id`, onDelete CASCADE)
|
|
496
|
+
- `step_type` (enum: `course`, `exam`)
|
|
497
|
+
- `course_id` (FK opcional para `course.id`, onDelete CASCADE)
|
|
498
|
+
- `exam_id` (FK opcional para `exam.id`, onDelete CASCADE)
|
|
499
|
+
- `order` (int)
|
|
500
|
+
- `is_required` (boolean, default true)
|
|
501
|
+
- `created_at`, `updated_at`
|
|
502
|
+
- **Índices:** únicos para combinações de trilha e ordem, curso ou exame.
|
|
503
|
+
|
|
504
|
+
### question
|
|
505
|
+
|
|
506
|
+
- **Finalidade:** Questões para avaliações e quizzes.
|
|
507
|
+
- **Colunas:**
|
|
508
|
+
- `id` (PK)
|
|
509
|
+
- `question_type` (enum: `multiple_choice`, `true_false`, `essay`, `fill_blank`, `matching`)
|
|
510
|
+
- `statement` (text)
|
|
511
|
+
- `explanation` (text, nullable)
|
|
512
|
+
- `points` (int, default 1)
|
|
513
|
+
- `created_at`, `updated_at`
|
|
514
|
+
|
|
515
|
+
## 8. Regras de negócio relevantes
|
|
516
|
+
|
|
517
|
+
- Certificados são vinculados a estudantes e podem estar associados a diferentes tipos de atividades (curso, exame, grupo de aula, trilha).
|
|
518
|
+
- Cursos, exames e trilhas possuem status que controlam sua visibilidade e disponibilidade.
|
|
519
|
+
- Matrículas e inscrições possuem status que refletem o progresso e situação do aluno.
|
|
520
|
+
- Avaliações e tentativas de exame são controladas para permitir múltiplas tentativas e registrar resultados detalhados.
|
|
521
|
+
- Instrutores podem ter papéis distintos (líder ou assistente) em aulas e sessões.
|
|
522
|
+
- Trilhas de aprendizagem são compostas por passos ordenados que podem ser cursos ou exames, podendo ser obrigatórios ou opcionais.
|
|
523
|
+
- Progresso em aulas e cursos é monitorado para permitir acompanhamento detalhado do aluno.
|
|
524
|
+
- Imagens e arquivos são organizados por tipo e podem ser marcados como primários para exibição.
|
|
525
|
+
|
|
526
|
+
## 9. Guia rápido de uso (exemplos)
|
|
527
|
+
|
|
528
|
+
> Como o módulo não expõe endpoints diretamente, o uso típico envolve integração via serviços internos ou APIs do HedHog.
|
|
529
|
+
|
|
530
|
+
### Exemplo: Criar um novo curso
|
|
531
|
+
|
|
532
|
+
```ts
|
|
533
|
+
const novoCurso = await prisma.course.create({
|
|
534
|
+
data: {
|
|
535
|
+
title: 'Introdução ao HedHog LMS',
|
|
536
|
+
slug: 'introducao-hedhog-lms',
|
|
537
|
+
description: 'Curso básico para entender o LMS HedHog',
|
|
538
|
+
level: 'beginner',
|
|
539
|
+
duration_hours: 10,
|
|
540
|
+
status: 'draft',
|
|
541
|
+
},
|
|
542
|
+
});
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### Exemplo: Matricular um estudante em um curso
|
|
546
|
+
|
|
547
|
+
```ts
|
|
548
|
+
const matricula = await prisma.course_enrollment.create({
|
|
549
|
+
data: {
|
|
550
|
+
person_id: estudanteId,
|
|
551
|
+
course_id: cursoId,
|
|
552
|
+
status: 'active',
|
|
553
|
+
enrolled_at: new Date(),
|
|
554
|
+
},
|
|
555
|
+
});
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### Exemplo: Registrar presença em uma sessão de aula
|
|
559
|
+
|
|
560
|
+
```ts
|
|
561
|
+
const presenca = await prisma.course_class_attendance.upsert({
|
|
562
|
+
where: {
|
|
563
|
+
course_class_session_id_student_id: {
|
|
564
|
+
course_class_session_id: sessaoId,
|
|
565
|
+
student_id: estudanteId,
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
update: { present: true },
|
|
569
|
+
create: {
|
|
570
|
+
course_class_session_id: sessaoId,
|
|
571
|
+
student_id: estudanteId,
|
|
572
|
+
present: true,
|
|
573
|
+
},
|
|
574
|
+
});
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Exemplo: Emitir um certificado
|
|
578
|
+
|
|
579
|
+
```ts
|
|
580
|
+
const certificado = await prisma.certificate.create({
|
|
581
|
+
data: {
|
|
582
|
+
verification_code: gerarCodigoUnico(),
|
|
583
|
+
student_id: estudanteId,
|
|
584
|
+
course_id: cursoId,
|
|
585
|
+
certificate_template_id: templateId,
|
|
586
|
+
certificate_type: 'course',
|
|
587
|
+
student_name: nomeEstudante,
|
|
588
|
+
course_name: nomeCurso,
|
|
589
|
+
workload_hours: cargaHoraria,
|
|
590
|
+
issued_at: new Date(),
|
|
591
|
+
completed_at: dataConclusao,
|
|
592
|
+
final_score: notaFinal,
|
|
593
|
+
verification_url: urlVerificacao,
|
|
594
|
+
pdf_url: urlPdf,
|
|
595
|
+
},
|
|
596
|
+
});
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
---
|
|
600
|
+
|
|
601
|
+
Para mais detalhes sobre integração e uso, consulte a documentação geral do HedHog e os serviços que consomem o módulo `@hed-hog/lms`.
|
|
602
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hed-hog/lms",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.275",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
"@nestjs/core": "^11",
|
|
10
10
|
"@nestjs/jwt": "^11",
|
|
11
11
|
"@nestjs/mapped-types": "*",
|
|
12
|
-
"@hed-hog/
|
|
13
|
-
"@hed-hog/core": "0.0.270",
|
|
12
|
+
"@hed-hog/core": "0.0.275",
|
|
14
13
|
"@hed-hog/api": "0.0.4",
|
|
15
|
-
"@hed-hog/
|
|
14
|
+
"@hed-hog/finance": "0.0.275",
|
|
16
15
|
"@hed-hog/api-types": "0.0.1",
|
|
17
|
-
"@hed-hog/
|
|
18
|
-
"@hed-hog/contact": "0.0.
|
|
19
|
-
"@hed-hog/
|
|
20
|
-
"@hed-hog/api-
|
|
16
|
+
"@hed-hog/api-pagination": "0.0.6",
|
|
17
|
+
"@hed-hog/contact": "0.0.275",
|
|
18
|
+
"@hed-hog/api-prisma": "0.0.5",
|
|
19
|
+
"@hed-hog/api-locale": "0.0.13",
|
|
20
|
+
"@hed-hog/category": "0.0.275"
|
|
21
21
|
},
|
|
22
22
|
"exports": {
|
|
23
23
|
".": {
|