@dirayaah/assessment-module 1.0.0

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.
Files changed (156) hide show
  1. package/.prettierrc +4 -0
  2. package/README copy.md +93 -0
  3. package/README.md +93 -0
  4. package/dist/index.d.ts +9 -0
  5. package/dist/index.js +26 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/jest.config.d.ts +0 -0
  8. package/dist/jest.config.js +10 -0
  9. package/dist/jest.config.js.map +1 -0
  10. package/dist/src/constants/assessments-options.d.ts +1 -0
  11. package/dist/src/constants/assessments-options.js +5 -0
  12. package/dist/src/constants/assessments-options.js.map +1 -0
  13. package/dist/src/constants/index.d.ts +3 -0
  14. package/dist/src/constants/index.js +10 -0
  15. package/dist/src/constants/index.js.map +1 -0
  16. package/dist/src/constants/predefined-assessments/disc.d.ts +3 -0
  17. package/dist/src/constants/predefined-assessments/disc.js +184 -0
  18. package/dist/src/constants/predefined-assessments/disc.js.map +1 -0
  19. package/dist/src/constants/predefined-assessments/holland.d.ts +3 -0
  20. package/dist/src/constants/predefined-assessments/holland.js +208 -0
  21. package/dist/src/constants/predefined-assessments/holland.js.map +1 -0
  22. package/dist/src/constants/predefined-assessments/index.d.ts +4 -0
  23. package/dist/src/constants/predefined-assessments/index.js +10 -0
  24. package/dist/src/constants/predefined-assessments/index.js.map +1 -0
  25. package/dist/src/constants/predefined-assessments/leadership.d.ts +3 -0
  26. package/dist/src/constants/predefined-assessments/leadership.js +211 -0
  27. package/dist/src/constants/predefined-assessments/leadership.js.map +1 -0
  28. package/dist/src/dto/assessment.dto.d.ts +14 -0
  29. package/dist/src/dto/assessment.dto.js +88 -0
  30. package/dist/src/dto/assessment.dto.js.map +1 -0
  31. package/dist/src/dto/base.dto.d.ts +7 -0
  32. package/dist/src/dto/base.dto.js +7 -0
  33. package/dist/src/dto/base.dto.js.map +1 -0
  34. package/dist/src/dto/index.d.ts +3 -0
  35. package/dist/src/dto/index.js +8 -0
  36. package/dist/src/dto/index.js.map +1 -0
  37. package/dist/src/dto/predefined-assessment.dto.d.ts +12 -0
  38. package/dist/src/dto/predefined-assessment.dto.js +74 -0
  39. package/dist/src/dto/predefined-assessment.dto.js.map +1 -0
  40. package/dist/src/entities/assessment.entity.d.ts +15 -0
  41. package/dist/src/entities/assessment.entity.js +69 -0
  42. package/dist/src/entities/assessment.entity.js.map +1 -0
  43. package/dist/src/entities/base.entity.d.ts +7 -0
  44. package/dist/src/entities/base.entity.js +37 -0
  45. package/dist/src/entities/base.entity.js.map +1 -0
  46. package/dist/src/entities/index.d.ts +3 -0
  47. package/dist/src/entities/index.js +8 -0
  48. package/dist/src/entities/index.js.map +1 -0
  49. package/dist/src/entities/pagination.d.ts +19 -0
  50. package/dist/src/entities/pagination.js +58 -0
  51. package/dist/src/entities/pagination.js.map +1 -0
  52. package/dist/src/entities/predefined-assessment.entity.d.ts +13 -0
  53. package/dist/src/entities/predefined-assessment.entity.js +55 -0
  54. package/dist/src/entities/predefined-assessment.entity.js.map +1 -0
  55. package/dist/src/enums/index.d.ts +3 -0
  56. package/dist/src/enums/index.js +8 -0
  57. package/dist/src/enums/index.js.map +1 -0
  58. package/dist/src/enums/language.d.ts +5 -0
  59. package/dist/src/enums/language.js +10 -0
  60. package/dist/src/enums/language.js.map +1 -0
  61. package/dist/src/enums/predefined-assessment-type.d.ts +5 -0
  62. package/dist/src/enums/predefined-assessment-type.js +10 -0
  63. package/dist/src/enums/predefined-assessment-type.js.map +1 -0
  64. package/dist/src/interfaces/assessments-options.interface.d.ts +6 -0
  65. package/dist/src/interfaces/assessments-options.interface.js +3 -0
  66. package/dist/src/interfaces/assessments-options.interface.js.map +1 -0
  67. package/dist/src/mappers/assessment.mapper.d.ts +6 -0
  68. package/dist/src/mappers/assessment.mapper.js +31 -0
  69. package/dist/src/mappers/assessment.mapper.js.map +1 -0
  70. package/dist/src/mappers/predefined-assessment.mapper.d.ts +6 -0
  71. package/dist/src/mappers/predefined-assessment.mapper.js +31 -0
  72. package/dist/src/mappers/predefined-assessment.mapper.js.map +1 -0
  73. package/dist/src/migrations/1767108782301-CreateAssessmentTable.d.ts +5 -0
  74. package/dist/src/migrations/1767108782301-CreateAssessmentTable.js +83 -0
  75. package/dist/src/migrations/1767108782301-CreateAssessmentTable.js.map +1 -0
  76. package/dist/src/migrations/1767200020161-CreatePredefinedAssessmentTable.d.ts +6 -0
  77. package/dist/src/migrations/1767200020161-CreatePredefinedAssessmentTable.js +70 -0
  78. package/dist/src/migrations/1767200020161-CreatePredefinedAssessmentTable.js.map +1 -0
  79. package/dist/src/migrations/1767204696509-SeedPredefinedAssessments.d.ts +6 -0
  80. package/dist/src/migrations/1767204696509-SeedPredefinedAssessments.js +29 -0
  81. package/dist/src/migrations/1767204696509-SeedPredefinedAssessments.js.map +1 -0
  82. package/dist/src/migrations/1767651698587-AddMetaFieldsToAssessmentTable.d.ts +7 -0
  83. package/dist/src/migrations/1767651698587-AddMetaFieldsToAssessmentTable.js +60 -0
  84. package/dist/src/migrations/1767651698587-AddMetaFieldsToAssessmentTable.js.map +1 -0
  85. package/dist/src/migrations/index.d.ts +6 -0
  86. package/dist/src/migrations/index.js +18 -0
  87. package/dist/src/migrations/index.js.map +1 -0
  88. package/dist/src/modules/assessment.module.d.ts +5 -0
  89. package/dist/src/modules/assessment.module.js +34 -0
  90. package/dist/src/modules/assessment.module.js.map +1 -0
  91. package/dist/src/repositories/assessment.repository.d.ts +4 -0
  92. package/dist/src/repositories/assessment.repository.js +19 -0
  93. package/dist/src/repositories/assessment.repository.js.map +1 -0
  94. package/dist/src/repositories/base.repository.d.ts +10 -0
  95. package/dist/src/repositories/base.repository.js +29 -0
  96. package/dist/src/repositories/base.repository.js.map +1 -0
  97. package/dist/src/repositories/index.d.ts +3 -0
  98. package/dist/src/repositories/index.js +8 -0
  99. package/dist/src/repositories/index.js.map +1 -0
  100. package/dist/src/repositories/predefined-assessment.repository.d.ts +4 -0
  101. package/dist/src/repositories/predefined-assessment.repository.js +19 -0
  102. package/dist/src/repositories/predefined-assessment.repository.js.map +1 -0
  103. package/dist/src/services/assessment.service.d.ts +23 -0
  104. package/dist/src/services/assessment.service.js +108 -0
  105. package/dist/src/services/assessment.service.js.map +1 -0
  106. package/dist/src/services/index.d.ts +3 -0
  107. package/dist/src/services/index.js +8 -0
  108. package/dist/src/services/index.js.map +1 -0
  109. package/dist/src/services/predefined-assessment.service.d.ts +21 -0
  110. package/dist/src/services/predefined-assessment.service.js +95 -0
  111. package/dist/src/services/predefined-assessment.service.js.map +1 -0
  112. package/dist/src/utilities/migrations/get-base-columns.d.ts +2 -0
  113. package/dist/src/utilities/migrations/get-base-columns.js +34 -0
  114. package/dist/src/utilities/migrations/get-base-columns.js.map +1 -0
  115. package/dist/tsconfig.tsbuildinfo +1 -0
  116. package/index.ts +26 -0
  117. package/jest.config.ts +10 -0
  118. package/nest-cli.json +8 -0
  119. package/package.json +53 -0
  120. package/src/constants/assessments-options.ts +1 -0
  121. package/src/constants/index.ts +12 -0
  122. package/src/constants/predefined-assessments/disc.ts +205 -0
  123. package/src/constants/predefined-assessments/holland.ts +235 -0
  124. package/src/constants/predefined-assessments/index.ts +5 -0
  125. package/src/constants/predefined-assessments/leadership.ts +242 -0
  126. package/src/dto/assessment.dto.ts +69 -0
  127. package/src/dto/base.dto.ts +11 -0
  128. package/src/dto/index.ts +4 -0
  129. package/src/dto/predefined-assessment.dto.ts +59 -0
  130. package/src/entities/assessment.entity.ts +41 -0
  131. package/src/entities/base.entity.ts +23 -0
  132. package/src/entities/index.ts +4 -0
  133. package/src/entities/pagination.ts +42 -0
  134. package/src/entities/predefined-assessment.entity.ts +31 -0
  135. package/src/enums/index.ts +4 -0
  136. package/src/enums/language.ts +5 -0
  137. package/src/enums/predefined-assessment-type.ts +5 -0
  138. package/src/interfaces/assessments-options.interface.ts +6 -0
  139. package/src/mappers/assessment.mapper.ts +34 -0
  140. package/src/mappers/predefined-assessment.mapper.ts +36 -0
  141. package/src/migrations/1767108782301-CreateAssessmentTable.ts +88 -0
  142. package/src/migrations/1767200020161-CreatePredefinedAssessmentTable.ts +77 -0
  143. package/src/migrations/1767204696509-SeedPredefinedAssessments.ts +32 -0
  144. package/src/migrations/1767651698587-AddMetaFieldsToAssessmentTable.ts +88 -0
  145. package/src/migrations/index.ts +20 -0
  146. package/src/modules/assessment.module.ts +22 -0
  147. package/src/repositories/assessment.repository.ts +6 -0
  148. package/src/repositories/base.repository.ts +39 -0
  149. package/src/repositories/index.ts +4 -0
  150. package/src/repositories/predefined-assessment.repository.ts +6 -0
  151. package/src/services/assessment.service.ts +144 -0
  152. package/src/services/index.ts +4 -0
  153. package/src/services/predefined-assessment.service.ts +121 -0
  154. package/src/utilities/migrations/get-base-columns.ts +32 -0
  155. package/tsconfig.build.json +4 -0
  156. package/tsconfig.json +21 -0
@@ -0,0 +1,88 @@
1
+ import { baseColumns } from '../utilities/migrations/get-base-columns';
2
+ import {
3
+ MigrationInterface,
4
+ QueryRunner,
5
+ Table,
6
+ TableUnique,
7
+ } from 'typeorm/index.js';
8
+
9
+ export class CreateAssessmentTable1767108782301 implements MigrationInterface {
10
+ public async up(queryRunner: QueryRunner): Promise<void> {
11
+ const [idColumn, ...otherBaseColumns] = baseColumns;
12
+ await queryRunner.createTable(
13
+ new Table({
14
+ name: 'assessment',
15
+ columns: [
16
+ idColumn,
17
+ {
18
+ name: 'title',
19
+ type: 'varchar',
20
+ isNullable: false,
21
+ },
22
+ {
23
+ name: 'type',
24
+ type: 'varchar',
25
+ isNullable: false,
26
+ },
27
+ {
28
+ name: 'description',
29
+ type: 'text',
30
+ isNullable: true,
31
+ },
32
+ {
33
+ name: 'background_image_url',
34
+ type: 'varchar',
35
+ isNullable: true,
36
+ },
37
+ {
38
+ name: 'price',
39
+ type: 'numeric',
40
+ isNullable: true,
41
+ },
42
+ {
43
+ name: 'discount_price',
44
+ type: 'numeric',
45
+ isNullable: true,
46
+ },
47
+ {
48
+ name: 'status',
49
+ type: 'varchar',
50
+ isNullable: true,
51
+ },
52
+ {
53
+ name: 'configuration',
54
+ type: 'json',
55
+ isNullable: true,
56
+ },
57
+ {
58
+ name: 'published_by',
59
+ type: 'varchar',
60
+ isNullable: true,
61
+ },
62
+ {
63
+ name: 'is_private',
64
+ type: 'boolean',
65
+ default: false,
66
+ },
67
+ {
68
+ name: 'slug',
69
+ type: 'varchar',
70
+ isNullable: false,
71
+ },
72
+ {
73
+ name: 'meta_description',
74
+ type: 'varchar',
75
+ isNullable: true,
76
+ },
77
+ ...otherBaseColumns,
78
+ ],
79
+ uniques: [{ columnNames: ['slug'] }],
80
+ }),
81
+ true,
82
+ );
83
+ }
84
+
85
+ public async down(queryRunner: QueryRunner): Promise<void> {
86
+ await queryRunner.dropTable('assessment');
87
+ }
88
+ }
@@ -0,0 +1,77 @@
1
+ import { PredefinedAssessmentType } from '../enums';
2
+ import { AssessmentDetailsLanguage } from '../enums/language';
3
+ import { baseColumns } from '../utilities/migrations/get-base-columns';
4
+ import {
5
+ Column,
6
+ Entity,
7
+ MigrationInterface,
8
+ OneToMany,
9
+ QueryRunner,
10
+ Table,
11
+ } from 'typeorm/index.js';
12
+
13
+ export class CreatePredefinedAssessmentTable1767200020161
14
+ implements MigrationInterface
15
+ {
16
+ private readonly tableName = 'predefined_assessment';
17
+ public async up(queryRunner: QueryRunner): Promise<void> {
18
+ const [idColumn, ...otherBaseColumns] = baseColumns;
19
+ await queryRunner.createTable(
20
+ new Table({
21
+ name: this.tableName,
22
+ columns: [
23
+ idColumn,
24
+ {
25
+ name: 'title',
26
+ type: 'varchar',
27
+ isNullable: false,
28
+ },
29
+ {
30
+ name: 'type',
31
+ type: 'enum',
32
+ enum: Object.values(PredefinedAssessmentType),
33
+ isNullable: false,
34
+ },
35
+ {
36
+ name: 'description',
37
+ type: 'text',
38
+ isNullable: true,
39
+ },
40
+ {
41
+ name: 'background_image_url',
42
+ type: 'varchar',
43
+ isNullable: true,
44
+ },
45
+ {
46
+ name: 'language',
47
+ type: 'enum',
48
+ enum: Object.values(AssessmentDetailsLanguage),
49
+ isNullable: false,
50
+ },
51
+ {
52
+ name: 'category',
53
+ type: 'varchar',
54
+ isNullable: true,
55
+ },
56
+ {
57
+ name: 'details',
58
+ type: 'json',
59
+ isNullable: false,
60
+ },
61
+ {
62
+ name: 'configuration',
63
+ type: 'json',
64
+ isNullable: true,
65
+ },
66
+ ...otherBaseColumns,
67
+ ],
68
+ uniques: [{ columnNames: ['type', 'language'] }],
69
+ }),
70
+ true,
71
+ );
72
+ }
73
+
74
+ public async down(queryRunner: QueryRunner): Promise<void> {
75
+ await queryRunner.dropTable(this.tableName);
76
+ }
77
+ }
@@ -0,0 +1,32 @@
1
+ import { PredefinedAssessmentEntity } from '../entities';
2
+ import {
3
+ DISC_ASSESSMENT,
4
+ HOLLAND_ASSESSMENT,
5
+ LEADERSHIP_ASSESSMENT,
6
+ } from '../constants';
7
+ import { MigrationInterface, QueryRunner } from 'typeorm/index.js';
8
+
9
+ export class SeedPredefinedAssessments1767204696509
10
+ implements MigrationInterface
11
+ {
12
+ private readonly tableName = 'predefined_assessment';
13
+
14
+ public async up(queryRunner: QueryRunner): Promise<void> {
15
+ const assessments = [
16
+ ...DISC_ASSESSMENT,
17
+ ...HOLLAND_ASSESSMENT,
18
+ ...LEADERSHIP_ASSESSMENT,
19
+ ].map((item) => ({
20
+ ...item,
21
+ configuration: item.configuration ?? {},
22
+ }));
23
+
24
+ for (const assessment of assessments) {
25
+ await queryRunner.manager.save(queryRunner.manager.create(PredefinedAssessmentEntity, assessment));
26
+ };
27
+ }
28
+
29
+ public async down(queryRunner: QueryRunner): Promise<void> {
30
+ await queryRunner.query(`DELETE FROM "${this.tableName}"`);
31
+ }
32
+ }
@@ -0,0 +1,88 @@
1
+ import {
2
+ MigrationInterface,
3
+ QueryRunner,
4
+ TableColumn,
5
+ TableUnique,
6
+ } from 'typeorm/index.js';
7
+
8
+ export class AddMetaFieldsToAssessmentTable1767651698587
9
+ implements MigrationInterface
10
+ {
11
+ private readonly tableName = 'assessment';
12
+ private readonly slugUniqueConstraintName = `UQ_${this.tableName}_slug`;
13
+
14
+ public async up(queryRunner: QueryRunner): Promise<void> {
15
+ const table = await queryRunner.getTable(this.tableName);
16
+ if (!table) {
17
+ throw new Error(`Table ${this.tableName} does not exist`);
18
+ }
19
+
20
+ const columnsToAdd: TableColumn[] = [];
21
+
22
+ if (!table.findColumnByName('slug')) {
23
+ columnsToAdd.push(
24
+ new TableColumn({
25
+ name: 'slug',
26
+ type: 'varchar',
27
+ isNullable: false,
28
+ }),
29
+ );
30
+ }
31
+
32
+ if (!table.findColumnByName('meta_description')) {
33
+ columnsToAdd.push(
34
+ new TableColumn({
35
+ name: 'meta_description',
36
+ type: 'varchar',
37
+ isNullable: true,
38
+ }),
39
+ );
40
+ }
41
+
42
+ if (columnsToAdd.length > 0) {
43
+ await queryRunner.addColumns(this.tableName, columnsToAdd);
44
+ }
45
+
46
+ // Check if slug unique constraint already exists
47
+ // Refresh table to get latest state after adding columns
48
+ const refreshedTable = await queryRunner.getTable(this.tableName);
49
+ if (refreshedTable) {
50
+ const slugColumn = refreshedTable.findColumnByName('slug');
51
+ if (slugColumn) {
52
+ const existingConstraint = refreshedTable.uniques.find(
53
+ (u) => u.name === this.slugUniqueConstraintName,
54
+ );
55
+ // Also check if there's any unique constraint on slug column
56
+ const hasSlugUnique = refreshedTable.uniques.some((u) =>
57
+ u.columnNames.includes('slug'),
58
+ );
59
+ if (!existingConstraint && !hasSlugUnique) {
60
+ await queryRunner.createUniqueConstraint(
61
+ this.tableName,
62
+ new TableUnique({
63
+ name: this.slugUniqueConstraintName,
64
+ columnNames: ['slug'],
65
+ }),
66
+ );
67
+ }
68
+ }
69
+ }
70
+ }
71
+
72
+ public async down(queryRunner: QueryRunner): Promise<void> {
73
+ const constraintExists = await queryRunner.getTable(this.tableName);
74
+ if (constraintExists) {
75
+ const uniqueConstraint = constraintExists.uniques.find(
76
+ (u) => u.name === this.slugUniqueConstraintName,
77
+ );
78
+ if (uniqueConstraint) {
79
+ await queryRunner.dropUniqueConstraint(
80
+ this.tableName,
81
+ this.slugUniqueConstraintName,
82
+ );
83
+ }
84
+ }
85
+
86
+ await queryRunner.dropColumns(this.tableName, ['slug', 'meta_description']);
87
+ }
88
+ }
@@ -0,0 +1,20 @@
1
+ import { CreateAssessmentTable1767108782301 } from './1767108782301-CreateAssessmentTable';
2
+
3
+ import { CreatePredefinedAssessmentTable1767200020161 } from './1767200020161-CreatePredefinedAssessmentTable';
4
+
5
+ import { SeedPredefinedAssessments1767204696509 } from './1767204696509-SeedPredefinedAssessments';
6
+
7
+ import { AddMetaFieldsToAssessmentTable1767651698587 } from './1767651698587-AddMetaFieldsToAssessmentTable';
8
+ export const AssessmentMigrations = [
9
+ CreateAssessmentTable1767108782301,
10
+ CreatePredefinedAssessmentTable1767200020161,
11
+ SeedPredefinedAssessments1767204696509,
12
+ AddMetaFieldsToAssessmentTable1767651698587,
13
+ ];
14
+
15
+ export {
16
+ CreateAssessmentTable1767108782301,
17
+ CreatePredefinedAssessmentTable1767200020161,
18
+ SeedPredefinedAssessments1767204696509,
19
+ AddMetaFieldsToAssessmentTable1767651698587,
20
+ };
@@ -0,0 +1,22 @@
1
+ import { DynamicModule, Module } from '@nestjs/common';
2
+ import { AssessmentService, PredefinedAssessmentService } from '../services';
3
+ import { AssessmentModuleOptions } from '../interfaces/assessments-options.interface';
4
+ import { ASSESSMENTS_OPTIONS } from '../constants';
5
+
6
+ @Module({})
7
+ export class AssessmentModule {
8
+ static forRoot(options: AssessmentModuleOptions): DynamicModule {
9
+ return {
10
+ module: AssessmentModule,
11
+ providers: [
12
+ {
13
+ provide: ASSESSMENTS_OPTIONS,
14
+ useValue: options,
15
+ },
16
+ AssessmentService,
17
+ PredefinedAssessmentService,
18
+ ],
19
+ exports: [AssessmentService, PredefinedAssessmentService],
20
+ };
21
+ }
22
+ }
@@ -0,0 +1,6 @@
1
+ import { AssessmentEntity } from '../entities';
2
+ import { EntityRepository } from 'typeorm/index.js';
3
+ import { BaseRepository } from './base.repository';
4
+
5
+ @EntityRepository(AssessmentEntity)
6
+ export class AssessmentRepository extends BaseRepository<AssessmentEntity> {}
@@ -0,0 +1,39 @@
1
+
2
+ import { FindManyOptions, FindOneOptions, Repository } from 'typeorm/index.js';
3
+ import { BaseEntity } from '../entities/base.entity';
4
+ import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
5
+ import { DeepPartial } from 'typeorm/browser';
6
+
7
+ export abstract class BaseRepository<
8
+ T extends BaseEntity,
9
+ > extends Repository<T> {
10
+ async findById(id: string): Promise<T | undefined> {
11
+ return this.findOne({ where: { id } } as FindOneOptions<T>);
12
+ }
13
+
14
+ async findWithOptions(options: FindManyOptions<T>): Promise<[T[], number]> {
15
+ return this.findAndCount(options);
16
+ }
17
+
18
+ async createEntity(data: DeepPartial<T>, creator?: string): Promise<T> {
19
+ const entity = this.create(data);
20
+ if (creator) {
21
+ entity.createdBy = creator;
22
+ entity.lastModifiedBy = creator;
23
+ }
24
+ return this.save(entity as DeepPartial<T>);
25
+ }
26
+
27
+ async updateEntity(
28
+ id: string,
29
+ data: QueryDeepPartialEntity<T>,
30
+ updater?: string,
31
+ ): Promise<T | undefined> {
32
+ await this.update(id, {
33
+ ...data,
34
+ updatedBy: updater,
35
+ } as QueryDeepPartialEntity<T>);
36
+
37
+ return this.findById(id);
38
+ }
39
+ }
@@ -0,0 +1,4 @@
1
+ import { AssessmentRepository } from './assessment.repository';
2
+ import { PredefinedAssessmentRepository } from './predefined-assessment.repository';
3
+
4
+ export { AssessmentRepository, PredefinedAssessmentRepository };
@@ -0,0 +1,6 @@
1
+ import { EntityRepository } from 'typeorm/index.js';
2
+ import { BaseRepository } from './base.repository';
3
+ import { PredefinedAssessmentEntity } from '../entities/predefined-assessment.entity';
4
+
5
+ @EntityRepository(PredefinedAssessmentEntity)
6
+ export class PredefinedAssessmentRepository extends BaseRepository<PredefinedAssessmentEntity> {}
@@ -0,0 +1,144 @@
1
+ import {
2
+ BadRequestException,
3
+ Inject,
4
+ Injectable,
5
+ NotFoundException,
6
+ } from '@nestjs/common';
7
+ import { ASSESSMENTS_OPTIONS } from '../constants/assessments-options';
8
+ import { AssessmentModuleOptions } from '../interfaces/assessments-options.interface';
9
+ import { AssessmentEntity } from '../entities';
10
+ import { AssessmentDto } from '../dto';
11
+ import { FindManyOptions, Repository } from 'typeorm/index.js';
12
+ import { PageRequest } from '../entities/pagination';
13
+ import { AssessmentMapper } from '../mappers/assessment.mapper';
14
+
15
+ @Injectable()
16
+ export class AssessmentService {
17
+ constructor(
18
+ @Inject(ASSESSMENTS_OPTIONS)
19
+ private readonly options: AssessmentModuleOptions,
20
+ ) {}
21
+
22
+ private async getRepository(
23
+ tenantId: string,
24
+ ): Promise<Repository<AssessmentEntity>> {
25
+ const connection =
26
+ await this.options.connectionProvider.getTenantConnection(tenantId);
27
+ return connection.getRepository(AssessmentEntity);
28
+ }
29
+
30
+ private async validateUniqueAssessmentSlug(
31
+ createAssessmentDto: AssessmentDto,
32
+ tenantId: string,
33
+ ) {
34
+ const assessment = await this.findOneByOptions(
35
+ {
36
+ where: [{ slug: createAssessmentDto.slug }],
37
+ },
38
+ tenantId,
39
+ );
40
+ if (assessment) {
41
+ throw new BadRequestException('ASSESSMENT_SLUG_ALREADY_EXISTS');
42
+ }
43
+ }
44
+
45
+ async create(createAssessmentDto: AssessmentDto, tenantId: string) {
46
+ const repository = await this.getRepository(tenantId);
47
+
48
+ const assessmentEntity =
49
+ AssessmentMapper.fromDTOToEntity(createAssessmentDto);
50
+
51
+ return repository.save(assessmentEntity);
52
+ }
53
+
54
+ async findAll(tenantId: string): Promise<AssessmentDto[]> {
55
+ const repository = await this.getRepository(tenantId);
56
+ const assessments = await repository
57
+ .createQueryBuilder('assessment')
58
+ .getMany();
59
+ return assessments.map((assessment) =>
60
+ AssessmentMapper.fromEntityToDTO(assessment),
61
+ );
62
+ }
63
+
64
+ async findByOptions(
65
+ options: FindManyOptions<AssessmentEntity>,
66
+ tenantId: string,
67
+ ): Promise<AssessmentDto[]> {
68
+ const repository = await this.getRepository(tenantId);
69
+ const assessments = await repository.find(options);
70
+ return assessments.map((assessment) =>
71
+ AssessmentMapper.fromEntityToDTO(assessment),
72
+ );
73
+ }
74
+
75
+ async findOne(id: number, tenantId: string): Promise<AssessmentDto> {
76
+ const repository = await this.getRepository(tenantId);
77
+
78
+ const assessment = await repository
79
+ .createQueryBuilder('assessment')
80
+ .where('assessment.id = :id', { id })
81
+ .getOne();
82
+
83
+ return AssessmentMapper.fromEntityToDTO(assessment);
84
+ }
85
+
86
+ async findOneBySlug(slug: string, tenantId: string): Promise<AssessmentDto> {
87
+ const repository = await this.getRepository(tenantId);
88
+
89
+ const assessment = await repository
90
+ .createQueryBuilder('assessment')
91
+ .where('assessment.slug = :slug', { slug })
92
+ .getOne();
93
+
94
+ return AssessmentMapper.fromEntityToDTO(assessment);
95
+ }
96
+
97
+ async findOneByOptions(
98
+ options: FindManyOptions<AssessmentEntity>,
99
+ tenantId: string,
100
+ ): Promise<AssessmentDto> {
101
+ const repository = await this.getRepository(tenantId);
102
+ const assessment = await repository.findOne(options);
103
+ return AssessmentMapper.fromEntityToDTO(assessment);
104
+ }
105
+
106
+ async getPaginatedAssessments(
107
+ pageRequest: PageRequest,
108
+ tenantId: string,
109
+ ): Promise<{ result: AssessmentDto[]; totalCount: number }> {
110
+ const repository = await this.getRepository(tenantId);
111
+ const assessments = await repository
112
+ .createQueryBuilder('assessment')
113
+ .skip(pageRequest.page * pageRequest.size)
114
+ .take(pageRequest.size)
115
+ .orderBy('assessment.id', 'DESC')
116
+ .getMany();
117
+
118
+ const totalCount = await repository.count();
119
+ return {
120
+ result: assessments.map((assessment) =>
121
+ AssessmentMapper.fromEntityToDTO(assessment),
122
+ ),
123
+ totalCount,
124
+ };
125
+ }
126
+
127
+ async update(updateAssessmentDto: AssessmentDto, tenantId: string) {
128
+ const repository = await this.getRepository(tenantId);
129
+ const existingAssessment = await repository.findOne(updateAssessmentDto.id);
130
+ if (!existingAssessment) {
131
+ throw new NotFoundException('ASSESSMENT_DOES_NOT_EXIST');
132
+ }
133
+
134
+ const updateAssessmentEntity =
135
+ AssessmentMapper.fromDTOToEntity(updateAssessmentDto);
136
+
137
+ return repository.update(updateAssessmentDto.id, updateAssessmentEntity);
138
+ }
139
+
140
+ async remove(id: number, tenantId: string) {
141
+ const repository = await this.getRepository(tenantId);
142
+ return await repository.delete(id);
143
+ }
144
+ }
@@ -0,0 +1,4 @@
1
+ import { AssessmentService } from './assessment.service';
2
+ import { PredefinedAssessmentService } from './predefined-assessment.service';
3
+
4
+ export { AssessmentService, PredefinedAssessmentService };
@@ -0,0 +1,121 @@
1
+ import { Inject, Injectable, NotFoundException } from '@nestjs/common';
2
+ import { ASSESSMENTS_OPTIONS } from '../constants/assessments-options';
3
+ import { AssessmentModuleOptions } from '../interfaces/assessments-options.interface';
4
+ import { FindManyOptions, Repository } from 'typeorm/index.js';
5
+ import { PageRequest } from '../entities/pagination';
6
+ import { PredefinedAssessmentEntity } from '../entities/predefined-assessment.entity';
7
+ import { PredefinedAssessmentDto } from '../dto/predefined-assessment.dto';
8
+ import { PredefinedAssessmentMapper } from '../mappers/predefined-assessment.mapper';
9
+
10
+ @Injectable()
11
+ export class PredefinedAssessmentService {
12
+ constructor(
13
+ @Inject(ASSESSMENTS_OPTIONS)
14
+ private readonly options: AssessmentModuleOptions,
15
+ ) {}
16
+
17
+ private async getRepository(
18
+ tenantId: string,
19
+ ): Promise<Repository<PredefinedAssessmentEntity>> {
20
+ const connection =
21
+ await this.options.connectionProvider.getTenantConnection(tenantId);
22
+ return connection.getRepository(PredefinedAssessmentEntity);
23
+ }
24
+
25
+ async findAll(tenantId: string): Promise<PredefinedAssessmentDto[]> {
26
+ const repository = await this.getRepository(tenantId);
27
+ const predefinedAssessments = await repository
28
+ .createQueryBuilder('assessment')
29
+ .getMany();
30
+ return predefinedAssessments.map((assessment) =>
31
+ PredefinedAssessmentMapper.fromEntityToDTO(assessment),
32
+ );
33
+ }
34
+
35
+ async findByOptions(
36
+ options: FindManyOptions<PredefinedAssessmentEntity>,
37
+ tenantId: string,
38
+ ): Promise<PredefinedAssessmentDto[]> {
39
+ const repository = await this.getRepository(tenantId);
40
+ const assessments = await repository.find(options);
41
+ return assessments.map((assessment) =>
42
+ PredefinedAssessmentMapper.fromEntityToDTO(assessment),
43
+ );
44
+ }
45
+
46
+ async findOne(
47
+ id: number,
48
+ tenantId: string,
49
+ ): Promise<PredefinedAssessmentDto> {
50
+ const repository = await this.getRepository(tenantId);
51
+
52
+ const predefinedAssessment = await repository
53
+ .createQueryBuilder('assessment')
54
+ .where('assessment.id = :id', { id })
55
+ .getOne();
56
+
57
+ return PredefinedAssessmentMapper.fromEntityToDTO(predefinedAssessment);
58
+ }
59
+
60
+ async findOneBySlug(
61
+ slug: string,
62
+ tenantId: string,
63
+ ): Promise<PredefinedAssessmentDto> {
64
+ const repository = await this.getRepository(tenantId);
65
+
66
+ const predefinedAssessment = await repository
67
+ .createQueryBuilder('assessment')
68
+ .where('assessment.slug = :slug', { slug })
69
+ .getOne();
70
+
71
+ return PredefinedAssessmentMapper.fromEntityToDTO(predefinedAssessment);
72
+ }
73
+
74
+ async findOneByOptions(
75
+ options: FindManyOptions<PredefinedAssessmentEntity>,
76
+ tenantId: string,
77
+ ): Promise<PredefinedAssessmentDto> {
78
+ const repository = await this.getRepository(tenantId);
79
+ const assessment = await repository.findOne(options);
80
+ return PredefinedAssessmentMapper.fromEntityToDTO(assessment);
81
+ }
82
+
83
+ async getPaginatedAssessments(
84
+ pageRequest: PageRequest,
85
+ tenantId: string,
86
+ ): Promise<{ result: PredefinedAssessmentDto[]; totalCount: number }> {
87
+ const repository = await this.getRepository(tenantId);
88
+ const assessments = await repository
89
+ .createQueryBuilder('assessment')
90
+ .skip(pageRequest.page * pageRequest.size)
91
+ .take(pageRequest.size)
92
+ .orderBy('assessment.id', 'DESC')
93
+ .getMany();
94
+
95
+ const totalCount = await repository.count();
96
+ return {
97
+ result: assessments.map((assessment) =>
98
+ PredefinedAssessmentMapper.fromEntityToDTO(assessment),
99
+ ),
100
+ totalCount,
101
+ };
102
+ }
103
+
104
+ async update(updateAssessmentDto: PredefinedAssessmentDto, tenantId: string) {
105
+ const repository = await this.getRepository(tenantId);
106
+ const existingAssessment = await repository.findOne(updateAssessmentDto.id);
107
+ if (!existingAssessment) {
108
+ throw new NotFoundException('ASSESSMENT_DOES_NOT_EXIST');
109
+ }
110
+
111
+ const updateAssessmentEntity =
112
+ PredefinedAssessmentMapper.fromDTOToEntity(updateAssessmentDto);
113
+
114
+ return repository.update(updateAssessmentDto.id, updateAssessmentEntity);
115
+ }
116
+
117
+ async remove(id: number, tenantId: string) {
118
+ const repository = await this.getRepository(tenantId);
119
+ return await repository.delete(id);
120
+ }
121
+ }
@@ -0,0 +1,32 @@
1
+ import { TableColumnOptions } from 'typeorm/schema-builder/options/TableColumnOptions';
2
+
3
+ export const baseColumns: TableColumnOptions[] = [
4
+ {
5
+ name: 'id',
6
+ type: 'int4',
7
+ isPrimary: true,
8
+ isGenerated: true,
9
+ generationStrategy: 'increment',
10
+ },
11
+ {
12
+ name: 'createdDate',
13
+ type: 'timestamptz',
14
+ isNullable: true,
15
+ default: 'now()',
16
+ },
17
+ {
18
+ name: 'createdBy',
19
+ type: 'varchar',
20
+ isNullable: true,
21
+ },
22
+ {
23
+ name: 'lastModifiedDate',
24
+ type: 'timestamptz',
25
+ isNullable: true,
26
+ },
27
+ {
28
+ name: 'lastModifiedBy',
29
+ type: 'varchar',
30
+ isNullable: true,
31
+ },
32
+ ];